传送门 :安慰奶牛
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cstdlib> 5 6 using namespace std; 7 8 struct node{ 9 int x,y,w; 10 }; 11 12 node s[100010];//边 13 int sum;//记录最小时间 14 int f[10010];//表示各个顶点在不同的连通分量上。 (即所属父亲) 15 int talk[10010];// 记录 每个牧场的谈话时间 16 17 void init()//初始化 18 { 19 int i; 20 for(i=0;i<10010;i++) 21 f[i]=i; 22 } 23 24 int cmp(node a,node b) //排序,从小到大 25 { 26 return a.w<b.w; 27 } 28 29 void kruscal(int n,int l)//kruscal 入口 30 { 31 int q; 32 sort(s,s+l,cmp); 33 int num=1,j; //记录边的个数 34 int k=0;//循环边的下标 35 while(num<n) 36 { 37 if(f[s[k].x]!=f[s[k].y]) //判断这条边是否构成回路 38 { 39 num++; 40 sum+=s[k].w; 41 q=f[s[k].y]; 42 for(j=1;j<=n;j++)//循环每个和q相等的顶点父亲 . 43 { 44 if(f[j]==q) f[j]=f[s[k].x]; 45 } 46 } 47 k++;//循环每条边 48 } 49 } 50 int main() 51 { 52 53 int n,p,i; 54 while(~scanf("%d%d",&n,&p)) 55 { 56 init(); 57 sum=0; 58 int min=99999; 59 for(i=1;i<=n;i++)//找最小的顶点,从这一点出发 60 { 61 scanf("%d",&talk[i]); 62 if(min>talk[i]) min=talk[i]; 63 } 64 for(i=0;i<p;i++)//构造可以生成最小树的连通图。 65 { 66 scanf("%d%d%d",&s[i].x,&s[i].y,&s[i].w); 67 s[i].w=talk[s[i].x]+talk[s[i].y]+2*s[i].w; 68 } 69 kruscal(n,p); 70 printf("%d\n",sum+min); 71 //for(i=1;i<=n;i++) 最小生成树的顶点最后成为一个连通图,即f[i]都相等 72 // cout << f[i]<<endl; 73 } 74 }
kruskal解答
时间: 2024-10-13 06:52:20