HLD 2038 联系网络 最小生成树
联系网络 | ||||||
|
||||||
Description | ||||||
TwIStOy要建立一个联系网络,这样可以方便的联系到所有人。如果TwIStOy可以联系到A,A又可以联系到B,那么就认为 TwIStOy可以联系到B了。但是建立两个人之间的联系方式是需要一定的代价的,现在TwIStOy希望使用一个最小的代价联系到 所有人。 |
||||||
Input | ||||||
本题有多组数据,输入处理到文件结束。 每组输入第一行包括一个整数n,表示有n个人编号分别是0 ~ (n-1)。TwIStOy的编号总是0。 接下来的n行每行包括n个整数,第i行的第j个整数w表示编号为i的联系到编号为j的人所需要的代价是w。 当然这个是一定满足w[i,j] = w[j,i]的。 n <= 300 |
||||||
Output | ||||||
每组输出包括一行,一个整数表示最小代价。 | ||||||
Sample Input | ||||||
3 0 2 3 2 0 1 3 1 0
|
||||||
Sample Output | ||||||
3
|
||||||
Source | ||||||
2014 Winter Holiday Contest 5 | ||||||
Author | ||||||
TwIStOy |
分析:最小生成树
用Kruskal算法即可 具体分析见 算法导论 367页(Kurskal)和368页(Prim)的图
代码:
1 #include<iostream> 2 #include<string.h> 3 #include<stdio.h> 4 #include<algorithm> 5 using namespace std; 6 7 const int maxn=301; 8 9 struct network 10 { 11 int a; 12 int b; 13 int value; 14 }net[maxn*maxn]; 15 16 bool cmp(network n1,network n2) 17 { 18 return n1.value<n2.value; 19 } 20 21 int fa[maxn],sum; 22 23 int init(int x) 24 { 25 for(int i=0;i<=x;i++) 26 fa[i]=i; 27 } 28 29 int find(int x) 30 { 31 return fa[x] == x ? x : fa[x]=find(fa[x]); 32 } 33 34 int unin(int x,int y,int z) 35 { 36 int fx=find(x); 37 int fy=find(y); 38 if(fx!=fy) 39 { 40 sum+=z; 41 fa[fx]=fy; 42 } 43 } 44 int main() 45 { 46 int n,num; 47 ios::sync_with_stdio(false); 48 //freopen("aa.txt","r",stdin); 49 while(cin>>n) 50 { 51 init(n); 52 int k=0; 53 for(int i=0;i<n;i++) 54 { 55 for(int j=0;j<n;j++) 56 { 57 cin>>num; 58 net[k].a=i; 59 net[k].b=j; 60 net[k].value=num; 61 k++; 62 } 63 } 64 sort(net,net+k,cmp); 65 sum=0; 66 for(int i=0;i<k;i++) 67 unin(net[i].a,net[i].b,net[i].value); 68 cout<<sum<<endl; 69 } 70 return 0; 71 }