T1003 电话连线 codevs
时间限制: 1 s
空间限制: 128000 KB
题目等级 : 黄金 Gold
题目描述 Description
一个国家有n个城市。若干个城市之间有电话线连接,现在要增加m条电话线(电话线当然是双向的了),使得任意两个城市之间都直接或间接经过其他城市有电话线连接,你的程序应该能够找出最小费用及其一种连接方案。
输入描述 Input Description
输入文件的第一行是n的值(n<=100).
第二行至第n+1行是一个n*n的矩阵,第i行第j列的数如果为0表示城市i与城市j有电话线连接,否则为这两个城市之间的连接费用(范围不超过10000)。
输出描述 Output Description
输出文件的第一行为你连接的电话线总数m,第二行至第m+1行为你连接的每条电话线,格式为i j,(i<j), i j是电话线连接的两个城市。输出请按照Prim算法发现每一条边的顺序输出,起始点为1.
第m+2行是连接这些电话线的总费用。
样例输入 Sample Input
5
0 15 27 6 0
15 0 33 19 11
27 33 0 0 17
6 19 0 0 9
0 11 17 9 0
样例输出 Sample Output
2
1 4
2 5
17
数据范围及提示 Data Size & Hint
n<=100
1 #include <algorithm> 2 #include <iostream> 3 #include <cstdio> 4 #define INT int 5 #define N 105 6 #define maxn 1e7 7 8 using namespace std; 9 10 INT dis[N][N]; 11 INT n,minn,tot,k,ans; 12 INT d[N],son[N],fa[N]; 13 bool vis[N]; 14 15 void Prime() 16 { 17 for(int i=1;i<=n;i++) 18 { 19 d[i]=dis[1][i]; 20 fa[i]=1; 21 } 22 d[1]=0,vis[1]=1; 23 for(int i=1;i<n;i++) 24 { 25 minn=1e7; 26 for(int j=1;j<=n;j++) 27 if(!vis[j]&&minn>d[j]) 28 { 29 minn=d[j]; 30 k=j; 31 son[tot]=j; 32 } 33 ans+=minn; 34 vis[k]=1; 35 if(minn!=0&&minn!=1e7) 36 tot++; 37 for(int j=1;j<=n;j++) 38 if(!vis[j]&&d[j]>dis[k][j]) 39 { 40 d[j]=dis[k][j]; 41 fa[j]=k; 42 } 43 } 44 printf("%d\n",tot); 45 for(int i=0;i<tot;i++) 46 if(fa[son[i]]>son[i]) cout<<son[i]<<" "<<fa[son[i]]<<endl; 47 else cout<<fa[son[i]]<<" "<<son[i]<<endl; 48 printf("%d",ans); 49 } 50 51 int main() 52 { 53 scanf("%d",&n); 54 for(int i=1;i<=n;i++) 55 for(int j=1;j<=n;j++) 56 scanf("%d",&dis[i][j]); 57 Prime(); 58 return 0; 59 } 60 /* 61 5 62 0 15 27 6 0 63 15 0 33 19 11 64 27 33 0 0 17 65 6 19 0 0 9 66 0 11 17 9 0 67 */
——每当你想要放弃的时候,就想想是为了什么才一路坚持到现在。