DS图—最小生成树

题目描述

根据输入创建无向网。分别用Prim算法和Kruskal算法构建最小生成树。(假设:输入数据的最小生成树唯一。)

 

输入

顶点数n

 

n个顶点

 

边数m

 

m条边信息,格式为:顶点1 顶点2 权值

 

Prim算法的起点v

 

输出

输出最小生成树的权值之和

 

对两种算法,按树的生长顺序,输出边信息(Kruskal中边顶点按数组序号升序输出)

 

样例输入

6 v1 v2 v3 v4 v5 v6 10 v1 v2 6 v1 v3 1 v1 v4 5 v2 v3 5 v2 v5 3 v3 v4 5 v3 v5 6 v3 v6 4 v4 v6 2 v5 v6 6 v1

样例输出

15 prim: v1 v3 1 v3 v6 4 v6 v4 2 v3 v2 5 v2 v5 3 kruskal: v1 v3 1 v4 v6 2 v2 v5 3 v3 v6 4 v2 v3 5

提示

#include<iostream>
#include<queue>
#include<cstring>
using namespace std;
#define INF 0x3f
#define maxx 0x3f3f3f3f
#define in e
#define bef x1
#define aft x2
int array[INF][INF];
int visit[INF];
int n;
int e;
class edge
{
public:
    int x1;
    int x2;
    int data;
    int flag;
    edge()
    {
        x1=x2=-1;
        data=0;
        flag=0;
    }
    edge(int n1,int n2,int weight)
    {
        x1=n1;
        x2=n2;
        data=weight;
        flag=0;
    }
    friend bool operator>(const edge &a,const edge &b)
    {
        if(a.data>b.data)
            return true;
        else
            return false;
    }
};
 
int find(string str[],string st)
{
    for(int i=0;i<n;i++)
    {
        if(str[i]==st)
            return i;
    }
    return -1;
}
int check()
{
    for(int i=0;i<n;i++)
    {
        if(visit[i]==0)
            return 1;
    }
    return 0;
}
void prim(string str[],int start)
{
    memset(visit,0,sizeof(visit));
    int index=start;
    int sum=0;
    priority_queue< edge,vector<edge>,greater<edge> >T;
    string savex1[INF];
    string savex2[INF];
    int savew[INF];
    int count=0;
    while(check())
    {
        for(int i=0;i<n;i++)
        {
            if(array[index][i]!=maxx)
            {
                edge temp(index,i,array[index][i]);
                T.push(temp);
            }
        }
        while(visit[T.top().x2]==1)
        {
            T.pop();
        }
        savex1[count]=str[T.top().x1];
        savex2[count]=str[T.top().x2];
        savew[count]=T.top().data;
        sum+=T.top().data;
        visit[T.top().x1]=1;
        visit[T.top().x2]=1;
        count++;
        index=T.top().x2;
        T.pop();
    }
    cout<<sum<<endl;
    cout<<"prim:"<<endl;
    for(int i=0;i<count;i++)
    {
        cout<<savex1[i]<<" "<<savex2[i]<<" "<<savew[i]<<endl;
    }
}
int findmin(edge kr[])
{
    int minn=0x3f3f3f3f;
    int index=0;
    for(int i=0;i<in;i++)
    {
        if(!kr[i].flag&&kr[i].data<minn)
        {
            minn=kr[i].data;
            index=i;
        }
    }
    return index;
}
void change(int tag[],int a,int b)
{
    for(int i=0;i<n;i++)
        if(tag[i]==a)
            tag[i]=b;
}
void kruskal(string str[],edge kr[])
{
    int visit[n];
    for(int i=0;i<n;i++)
        visit[i]=i;
    cout<<"kruskal:"<<endl;
    int k=0;
    while(true)
    {
        int minn=findmin(kr);///找出权重最小的边
        kr[minn].flag=1;
        int t1=kr[minn].bef;
        int t2=kr[minn].aft;
 
        if(visit[t1]!=visit[t2])
        {
            if(t1>t2)
                swap(t1,t2);
            cout<<str[t1]<<" "<<str[t2]<<" "<<kr[minn].data<<endl;
            change(visit,visit[t1],visit[t2]);///将两个顶点连通
        }
        k++;
        if(k>=in)
            break;
    }
}
int main()
{
    cin>>n;
    string str[n];
    for(int i=0;i<n;i++)
      cin>>str[i];
    for(int i=0;i<n;i++)
        for(int j=0;j<n;j++)
            array[i][j]=maxx;
    cin>>e;
    edge kr[e];
    for(int j=0;j<e;j++)
    {
        string s1;
        string s2;
        int weight;
        cin>>s1>>s2>>weight;
        int t1=find(str,s1);
        int t2=find(str,s2);
        array[t1][t2]=weight;
        array[t2][t1]=weight;
        //krushal
        kr[j].bef=t1;
        kr[j].aft=t2;
        kr[j].data=weight;
        kr[j].flag=0;
    }
    string s;
    cin>>s;
    int d=find(str,s);
    prim(str,d);
    kruskal(str,kr);
    return 0;
}
上一篇:docker---netowkr操作


下一篇:CATIA V6 二次开发—(1)概述