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 }