2627 村村通
2627 村村通
时间限制: 1 s
空间限制: 32000 KB
题目等级 : 黄金 Gold
题目描述 Description
农民约翰被选为他们镇的镇长!他其中一个竞选承诺就是在镇上建立起互联网,并连接到所有的农场。当然,他需要你的帮助。
约翰已经给他的农场安排了一条高速的网络线路,他想把这条线路共享给其他农场。为了用最小的消费,他想铺设最短的光纤去连接所有的农场。
你将得到一份各农场之间连接费用的列表,你必须找出能连接所有农场并所用光纤最短的方案。每两个农场间的距离不会超过100000
输入描述 Input Description
第一行: 农场的个数,N(3<=N<=100)。
第二行,某些行会紧接着另一些行。当然,对角线将会是0,因为不会有线路从第i个农..结尾: 后来的行包含了一个N*N的矩阵,表示每个农场之间的距离。理论上,他们是N行,每行由N个用空格分隔的数组成,实际上,他们限制在80个字符,因此场到它本身。
输出描述
Output Description
只有一个输出,其中包含连接到每个农场的光纤的最小长度。
样例输入
Sample Input
4
0 4 9 21
4 0 8 17
9 8 0 16
21 17 16 0
样例输出
Sample Output
28
数据范围及提示
Data Size & Hint
暂时无范围。
prim算法:
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 using namespace std; 5 bool vis[1001]; 6 int a[1001][1001],minn[1001]; 7 int main() 8 { 9 int n; 10 scanf("%d",&n); 11 for(int i=1;i<=n;i++) 12 for(int j=1;j<=n;j++) 13 { 14 cin>>a[i][j]; 15 } 16 memset(minn,999999,sizeof(minn));memset(vis,1,sizeof(vis)); 17 minn[1]=0; 18 19 for(int i=1;i<=n;i++) 20 { 21 int k=0; 22 for(int j=1;j<=n;j++) 23 if(vis[j]&&minn[j]<minn[k]) 24 k=j; 25 vis[k]=0; 26 for(int j=1;j<=n;j++) 27 { 28 if(vis[j]&&minn[j]>a[k][j]) 29 { 30 minn[j]=a[k][j]; 31 } 32 } 33 } 34 int ans=0; 35 for(int i=1;i<=n;i++) 36 { 37 ans+=minn[i]; 38 } 39 cout<<ans; 40 }
Kruskal算法:
1 #include<cstdio> 2 #include<algorithm> 3 #include<iostream> 4 using namespace std; 5 struct node{ 6 int x; 7 int y; 8 int v; 9 bool operator < (const node &aa)const 10 { 11 if(v<aa.v)return 1; 12 else return 0; 13 } 14 }a[10001]; 15 int father[100001]; 16 int find(int x){ 17 if(father[x]!=x) father[x]=find(father[x]); 18 return father[x]; 19 } 20 void unionn(int x,int y) 21 { 22 int fa=find(x); 23 int fb=find(y); 24 if(fa!=fb)father[fa]=fb; 25 //if(find(x)!=find(y))father[find(x)]=father[find(y)]; 26 } 27 int num=0; 28 int main() 29 { 30 int n,m=0,x; 31 scanf("%d",&n); 32 for(int i=1;i<=n;i++) 33 for(int j=1;j<=n;j++) 34 { 35 cin>>x; 36 if(x!=0) 37 { 38 m++; 39 a[++num].x=i; 40 a[num].y=j; 41 a[num].v=x; 42 } 43 } 44 int tot=0,k=0; 45 for(int i=1;i<=n;i++) 46 father[i]=i; 47 sort(a+1,a+m+1); 48 for(int i=1;i<=m;i++) 49 { 50 if(find(a[i].x)!=find(a[i].y)) 51 { 52 unionn(a[i].x,a[i].y); 53 tot+=a[i].v; 54 k++; 55 } 56 if(k==n-1)break; 57 } 58 cout<<tot<<endl; 59 return 0; 60 }