标签:nes std sample field body mes namespace mini 路径
题目链接:http://poj.org/problem?id=1679
Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 31378 | Accepted: 11306 |
Description
Input
Output
Sample Input
2 3 3 1 2 1 2 3 2 3 1 3 4 4 1 2 2 2 3 2 3 4 2 4 1 2
Sample Output
3 Not Unique!
Source
题解:
问:最小生成树是否唯一。
次小生成树模板题。
代码如下:
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <cstring> 5 using namespace std; 6 typedef long long LL; 7 const double EPS = 1e-6; 8 const int INF = 2e9; 9 const LL LNF = 9e18; 10 const int MOD = 1e9+7; 11 const int MAXN = 1e2+10; 12 13 int cost[MAXN][MAXN], lowc[MAXN], pre[MAXN], Max[MAXN][MAXN]; 14 bool vis[MAXN], used[MAXN][MAXN]; 15 16 int Prim(int st, int n) 17 { 18 int ret = 0; 19 memset(vis, false, sizeof(vis)); 20 memset(used, false, sizeof(used)); 21 memset(Max, 0, sizeof(Max)); 22 23 for(int i = 1; i<=n; i++) 24 lowc[i] = (i==st)?0:INF; 25 pre[st] = st; 26 27 for(int i = 1; i<=n; i++) 28 { 29 int k, minn = INF; 30 for(int j = 1; j<=n; j++) 31 if(!vis[j] && minn>lowc[j]) 32 minn = lowc[k=j]; 33 34 if(minn==INF) return -1; //不连通 35 vis[k] = true; 36 ret += minn; 37 used[pre[k]][k] = used[k][pre[k]] = true; //pre[k]-k的边加入生成树 38 for(int j = 1; j<=n; j++) 39 { 40 if(vis[j] && j!=k) //如果遇到已经加入生成树的点,则找到两点间路径上的最大权值。 41 Max[j][k] = Max[k][j] = max(Max[j][pre[k]], lowc[k]); //k的上一个点是pre[k] 42 if(!vis[j] && lowc[j]>cost[k][j]) //否则,进行松弛操作 43 { 44 lowc[j] = cost[k][j]; 45 pre[j] = k; 46 } 47 } 48 } 49 return (ret==INF)?-1:ret; 50 } 51 52 int SMST(int t1 ,int n) 53 { 54 int ret = INF; 55 for(int i = 1; i<=n; i++) //用生成树之外的一条边去代替生成树内的一条边 56 for(int j = i+1; j<=n; j++) 57 { 58 if(cost[i][j]!=INF && !used[i][j]) //去掉了i-j路径上的某条边,但又把i、j直接连上,所以还是一棵生成树。 59 ret = min(ret, t1+cost[i][j]-Max[i][j]); 60 } 61 return ret; 62 } 63 64 int main() 65 { 66 int T, n, m; 67 scanf("%d", &T); 68 while(T--) 69 { 70 71 scanf("%d%d",&n,&m); 72 for(int i = 1; i<=n; i++) 73 for(int j = 1; j<=n; j++) 74 cost[i][j] = (i==j)?0:INF; 75 76 for(int i = 1; i<=m; i++) 77 { 78 int u, v, w; 79 scanf("%d%d%d", &u, &v, &w); 80 cost[u][v] = cost[v][u] = w; 81 } 82 83 int t1 = Prim(1, n); 84 int t2 = SMST(t1, n); 85 if(t1!=-1 && t2!=-1 && t1!=t2) printf("%d\n", t1); 86 else printf("Not Unique!\n"); 87 } 88 }
POJ1679 The Unique MST —— 次小生成树
标签:nes std sample field body mes namespace mini 路径
原文地址:http://www.cnblogs.com/DOLFAMINGO/p/7538619.html