安慰奶牛

传送门 :安慰奶牛

 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
",sum+min);
71         //for(i=1;i<=n;i++) 最小生成树的顶点最后成为一个连通图,即f[i]都相等 
72         //    cout << f[i]<<endl; 
73     }
74 }
kruskal解答
原文地址:https://www.cnblogs.com/WDKER/p/5189798.html