HDU 1102 Constructing Roads

赤裸裸的最小生成树。

题目大意就是输入一个N表示有n个村庄,然后输入n行n列,第i行j个元素表示i村庄离j村庄的路数多远(所以i行i列一般为零),然后输入q,表示q条路已修,然后输入q对数就可以了。(权值为零)。求使其n个村庄最小的连通值。

需要注意的是可能会有重复的路出现,但是有不同的值。既然是求最小生成树,那么可以用prim算法在输入路的时候保证是最小的值。

代码如下

View Code
 1 #include<stdio.h>
 2 #include<string.h>
 3 #include<stdlib.h>
 4 int map[105][105];
 5 int vis[105];
 6 int prim(int n)
 7 {
 8     int pos,i,j,d[105],ans,min;
 9     memset(vis,0,sizeof(vis));
10     ans = 0;
11 
12     for(i = 2;i <= n;i++)
13     d[i] = map[1][i];
14 
15     vis[1] = 1;
16     for(i = 1;i < n;i++)//次数很重要
17     {
18         min = 0x7fffffff;
19         for(j = 2;j <= n;j++)//是1是2无所谓,因为不会差1
20         {
21             if(!vis[j] && min > d[j])
22             min = d[j],pos = j;
23         }
24         ans += min;
25         vis[pos] = 1;
26 
27         for(j = 2;j <= n;j++)
28         if(!vis[j] && map[pos][j] < d[j])//切记这里的判断大小的方向
29         d[j] = map[pos][j];
30     }
31     return ans;
32 }
33 int main()
34 {
35     int n,i,j,a,q,b,c,ans;
36     while(~scanf("%d",&n))
37     {
38         ans = 0;
39         for(i = 1;i <= n;i++)
40             for(j =1;j <= n;j++)
41             map[i][j] = 0x7fffffff;
42 
43         for(i = 1;i <= n;i++)
44         {
45             for(j =1;j <= n;j++)
46             {
47                 scanf("%d",&a);
48                 if(map[i][j] > a || map[j][i] > a)
49                 map[i][j] = map[j][i] = a;
50             }
51         }
52         scanf("%d",&q);
53         while(q--)
54         {
55             scanf("%d %d",&b,&c);
56             map[b][c] = map[c][b] = 0;
57         }
58 
59         ans = prim(n);
60         printf("%d\n",ans);
61 
62     }
63     return 0;
64 }
原文地址:https://www.cnblogs.com/0803yijia/p/2625720.html