codevs1003 电话连线

 

题目描述 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

 

正解:最小生成树

解题报告:

  现在每天只能刷一点水题。。。这题还真是傲娇,居然只能用prim。。。其实我都快忘了prim是什么了

 

 1 //It is made by jump~
 2 #include <iostream>
 3 #include <cstdlib>
 4 #include <cstring>
 5 #include <cstdio>
 6 #include <cmath>
 7 #include <algorithm>
 8 #include <ctime>
 9 #include <vector>
10 #include <queue>
11 #include <map>
12 #include <set>
13 #ifdef WIN32   
14 #define OT "%I64d"
15 #else
16 #define OT "%lld"
17 #endif
18 using namespace std;
19 typedef long long LL;
20 const int MAXN = 111;
21 const int inf = (1<<30);
22 int n,cnt;
23 int a[MAXN][MAXN];
24 bool vis[MAXN];
25 int low[MAXN];
26 int next[MAXN];
27 int ans;
28 
29 struct edge{
30     int s,t;
31 }e[MAXN];
32 
33 inline int getint()
34 {
35        int w=0,q=0;
36        char c=getchar();
37        while((c<'0' || c>'9') && c!='-') c=getchar();
38        if (c=='-')  q=1, c=getchar();
39        while (c>='0' && c<='9') w=w*10+c-'0', c=getchar();
40        return q ? -w : w;
41 }
42 
43 inline void solve(){
44     n=getint();
45     for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) a[i][j]=getint();
46 
47     for(int i=1;i<=n;i++) low[i]=inf;
48 
49     low[1]=0; 
50 
51     for(int i=1;i<=n;i++) {
52     int minl=inf; int jilu;
53     for(int j=1;j<=n;j++) if(!vis[j] && minl>low[j]) { minl=low[j]; jilu=j; }
54     ans+=minl;  vis[jilu]=1;
55     for(int j=2;j<=n;j++) if(!vis[j] && a[jilu][j]<low[j]) { low[j]=a[jilu][j]; next[j]=jilu; }
56     if(minl) { e[++cnt].s=jilu; e[cnt].t=next[jilu]; }    
57     }
58 
59     printf("%d\n",cnt);
60 
61     for(int i=1;i<=cnt;i++) {
62     if(e[i].s>e[i].t) swap(e[i].s,e[i].t);
63     printf("%d %d\n",e[i].s,e[i].t);
64     }
65 
66     printf("%d",ans);
67 }
68 
69 int main()
70 {
71   solve();
72   return 0;
73 }

 

posted @ 2016-06-21 20:06  ljh_2000  阅读(342)  评论(1编辑  收藏  举报