The Unique MST 【POJ - 1679】【最小生成樹】
阿新 • • 發佈:2018-11-30
題目連結
看到這道題的時候我心裡一驚,求不同的最小生成樹!我的天吶,然後又看到這麼多人過了,一想,一定是簡單的題,然後就用Kruskal做了個不同邊的等價值降序/升序連結邊的端點的序號快排處理,然後加上個兩次Kruskal果然是這樣!就這樣過了。
#include <iostream> #include <cstdio> #include <cmath> #include <string> #include <cstring> #include <algorithm> #include <limits> #include <vector> #include <stack> #include <queue> #include <set> #include <map> #define lowbit(x) ( x&(-x) ) #define pi 3.141592653589793 #define e 2.718281828459045 using namespace std; typedef unsigned long long ull; typedef long long ll; const int maxN = 105; int N, M, root[maxN], fa[maxN]; ll ans; bool vis[maxN]; struct Eddge { int no, to, val, id; Eddge(int a=0, int b=0, int c=0, int d=0):no(a), to(b), val(c), id(d) {} }a[maxN*maxN], b[maxN*maxN]; bool cmp_up(Eddge e1, Eddge e2) { if(e1.val == e2.val) return e1.no == e2.no?(e1.to<e2.to):(e1.no<e2.no); else return e1.val<e2.val; } bool cmp_down(Eddge e1, Eddge e2) { if(e1.val == e2.val) return e1.no == e2.no?(e1.to>e2.to):(e1.no>e2.no); else return e1.val<e2.val; } void init() { ans = 0; for(int i=1; i<=N; i++) { root[i] = fa[i] = i; vis[i] = false; } } int fid(int x) { return x==root[x]?x:(root[x] = fid(root[x])); } int father(int x) { return x==fa[x]?x:(fa[x] = father(fa[x])); } void Kruskal_A() { for(int i=1; i<=M; i++) { int x = a[i].no, y = a[i].to, val = a[i].val; int u = fid(x), v = fid(y); if(u != v) { root[u] = v; ans += val; vis[a[i].id] = true; } } } bool Kruskal_B() { for(int i=1; i<=M; i++) { int x = b[i].no, y = b[i].to; int u = father(x), v = father(y); if(u != v) { fa[u] = v; if(!vis[b[i].id]) return false; } } return true; } int main() { int T; scanf("%d", &T); while(T--) { scanf("%d%d", &N, &M); init(); for(int i=1; i<=M; i++) { scanf("%d%d%d", &a[i].no, &a[i].to, &a[i].val); if(a[i].no > a[i].to) swap(a[i].no, a[i].to); a[i].id = i; b[i] = a[i]; } sort(a+1, a+1+M, cmp_up); sort(b+1, b+1+M, cmp_down); Kruskal_A(); if(Kruskal_B()) printf("%lld\n", ans); else printf("Not Unique!\n"); } return 0; }