标签:style blog http color strong os
问题:POJ2485
本题求解生成树最大边的最小值
分析:
首先证明生成树最大边的最小值即最小生成树的最大边。
假设:生成树最大边的最小值比最小生成树的最大边更小。
不妨设C为G的一个最小生成树,e是其中的最大边。把e从C中去除,则C被分成C1,C2两个连通子集。假设存在最大边小于e的生成树CC,则CC中连接C1,C2两个点集的桥ee必定小于e。把C中的e换成ee,则 C1,C2,ee必定也生成一个生成树。该生成树长度小于C,与C是最小生成树的事实矛盾,故假设不成立。
因此必有:
生成树最大边的最小值 = 最小生成树的最大边。
故本题转化为求解已知图的最小生成树,用PRIM法即可。
AC代码:
1 //Memory: 532K Time: 172MS 2 #include <iostream> 3 #include <cstring> 4 #include <string> 5 #include <algorithm> 6 7 const int maxn = 501; 8 int g[maxn][maxn]; 9 bool vis[maxn]; 10 int d[maxn]; 11 int n, t; 12 int _min, _max; 13 14 void prim() 15 { 16 memset(vis, 0, sizeof(vis)); 17 vis[0] = 1; 18 int size = 1; 19 _max = 0; 20 for (int i = 1 ; i < n; i++){ 21 d[i] = g[0][i]; 22 } 23 while (size < n) { 24 _min = 65536; 25 int k; 26 for (int i = 1; i < n; i++) { 27 if ( !vis[i] && d[i] < _min) { 28 _min = d[i]; 29 k = i; 30 } 31 } 32 vis[k] = 1; 33 if (_min > _max) _max = _min; 34 35 for (int i = 0; i < n; i++) { 36 if ( !vis[i] && g[i][k] < d[i]) 37 d[i] = g[k][i]; 38 } 39 size++; 40 } 41 } 42 43 int main() 44 { 45 scanf("%d", &t); 46 while (t--){ 47 scanf("%d", &n); 48 for (int i = 0; i < n; i++) 49 for (int j = 0; j < n; j++) 50 scanf("%d", &g[i][j]); 51 prim(); 52 printf("%d\n", _max); 53 } 54 return 0; 55 }
标签:style blog http color strong os
原文地址:http://www.cnblogs.com/junxie/p/3820553.html