POJ 1679 The Unique MST (可做次小生成树模板)
http://poj.org/problem?id=1679
题意 : 判断一张图中是否存在独一无二的最小生成树
我是用次小生成树做的,因为刚看了相关的文章,所以就想来试试。
恩,具体思路就是 :先求出最小生成树的边权值和 min_n 然后再去枚举每一条构成 MST 的边,继续MST操作,只是在求MST的时候不用所枚举到的边,然后求出一个MST(需要保证构成一棵完整的树)来,和 min_n作比较,如果相等的话,说明它是Not Unique !否则继续枚举下一条边,如果都没的话就输出min_n。
//CNWSYCF #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <algorithm> using namespace std; typedef long long LL; const double INF = 100000007; const double eps = 1e-9; const int maxn = 10005; #define MIN(a,b) (a > b ? b : a) #define MAX(a,b) (a > b ? a : b) struct node { int x,y; int d; int flag; }q[maxn]; int p[maxn],N,M; int cmp(node a,node b) { return a.d < b.d; } void init() { for (int i=1;i<=N;i++) p[i] = i; } int Find(int x) { return x == p[x] ? x : p[x] = Find(p[x]); } bool Isok() { int t = Find(1); for (int i=2;i<=N;i++) if (Find(i) != t)return 0; return 1; } int F(int n) { init(); int sum = 0; for (int i=0;i<M;i++) { int x = Find(q[i].x); int y = Find(q[i].y); if (x != y && i != n) { p[x] = y; sum += q[i].d; } } if (Isok())return sum; else return -1; } int main() { int T; scanf("%d",&T); while (T--) { scanf("%d%d",&N,&M); init(); for (int i=0;i<M;i++) { scanf("%d%d%d",&q[i].x,&q[i].y,&q[i].d); q[i].flag = 0; } sort(q,q+M,cmp); int min_n = 0; for (int i=0;i<M;i++) { int x = Find(q[i].x); int y = Find(q[i].y); if (x != y) { p[x] = y; min_n += q[i].d; q[i].flag = 1; } } int flag = 0; for (int i=0;i<M;i++) { if (q[i].flag) { if (F(i) == min_n) { flag = 1; break ; } } } if (flag)printf("Not Unique!\n"); else printf("%d\n",min_n); } return 0; }