1. 程式人生 > >The Unique MST 【POJ - 1679】【最小生成樹】

The Unique MST 【POJ - 1679】【最小生成樹】

題目連結


  看到這道題的時候我心裡一驚,求不同的最小生成樹!我的天吶,然後又看到這麼多人過了,一想,一定是簡單的題,然後就用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;
}