首页 > 代码库 > POJ2485 最小生成树
POJ2485 最小生成树
问题: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 }
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。