【USACO 3.1.1】最短网络
【描述】
农民约翰被选为他们镇的镇长!他其中一个竞选承诺就是在镇上建立起互联网,并连接到所有的场。当然,他需要你的帮助。
约翰已经给他的农场安排了一条高速的网络线路,他想把这条线路共享给其他农场。为了用最小的消费,他想铺设最短的光纤去连接所有的农场。
你将得到一份各农场之间连接费用的列表,你必须找出能连接所有农场并所用光纤最短的方案。
每两个农场间的距离不会超过100000
约翰已经给他的农场安排了一条高速的网络线路,他想把这条线路共享给其他农场。为了用最小的消费,他想铺设最短的光纤去连接所有的农场。
你将得到一份各农场之间连接费用的列表,你必须找出能连接所有农场并所用光纤最短的方案。
每两个农场间的距离不会超过100000
【格式】
PROGRAM NAME: agrinet
INPUT FORMAT:(file agrinet.in)
第一行: | 农场的个数,N(3<=N<=100)。 |
第二行..结尾: | 后来的行包含了一个N*N的矩阵,表示每个农场之间的距离。理论上,他们是N行,每行由N个用空格分隔的数组成,实际上,他们限制在80个字符,因此,某些行会紧接着另一些行。当然,对角线将会是0,因为不会有线路从第i个农场到它本身。 |
OUTPUT FORMAT:(file agrinet.out)
只有一个输出,其中包含连接到每个农场的光纤的最小长度。
【分析】
不解释了,裸的最小生成树。
1 #include <cstdlib> 2 #include <iostream> 3 #include <cstdio> 4 #include <cstring> 5 #include <cmath> 6 #include <algorithm> 7 const int maxn=100+10; 8 using namespace std; 9 struct Edge 10 { 11 int u,v; 12 int w; 13 bool operator <(const Edge&b)const 14 { 15 return w<b.w; 16 } 17 }data[maxn*maxn]; 18 int n,map[maxn][maxn]; 19 int parent[maxn],point;//并查集 20 21 int find(int x) {return parent[x]>0?parent[x]=find(parent[x]):x;} 22 void kruskal(); 23 void merge(int a,int b);//加权法则 24 25 int main() 26 { 27 int i,j; 28 //文件操作 29 freopen("agrinet.in","r",stdin); 30 freopen("agrinet.out","w",stdout); 31 memset(parent,-1,sizeof(parent)); 32 scanf("%d",&n); 33 for (i=1;i<=n;i++) 34 for (j=1;j<=n;j++) 35 { 36 int w; 37 scanf("%d",&w); 38 //加边 39 if (i==j) continue; 40 data[point].u=i;data[point].v=j;data[point].w=w; 41 point++; 42 } 43 kruskal(); 44 return 0; 45 } 46 void kruskal() 47 { 48 int ans=0,i; 49 sort(data,data+point); 50 for (i=0;i<point;i++) 51 { 52 int u=data[i].u,v=data[i].v; 53 u=find(u);v=find(v); 54 if (u!=v) 55 { 56 merge(u,v); 57 ans+=data[i].w; 58 } 59 } 60 printf("%d",ans); 61 } 62 void merge(int x,int y) 63 { 64 x=find(x);y=find(y); 65 if (parent[x]>parent[y]) {parent[y]+=parent[x];parent[x]=y;} 66 else {parent[x]+=parent[y];parent[y]=x;} 67 }