1. 程式人生 > >POJ1679:The Unique MST(最小生成樹)

POJ1679:The Unique MST(最小生成樹)

nta efi algorithm tin direct ali nes class stream

The Unique MST

Time Limit: 1000MS Memory Limit: 10000K
Total Submissions: 38430 Accepted: 14045

題目鏈接:http://poj.org/problem?id=1679

Description:

Given a connected undirected graph, tell if its minimum spanning tree is unique.

Definition 1 (Spanning Tree): Consider a connected, undirected graph G = (V, E). A spanning tree of G is a subgraph of G, say T = (V‘, E‘), with the following properties:

1. V‘ = V.
2. T is connected and acyclic.

Definition 2 (Minimum Spanning Tree): Consider an edge-weighted, connected, undirected graph G = (V, E). The minimum spanning tree T = (V, E‘) of G is the spanning tree that has the smallest total cost. The total cost of T means the sum of the weights on all the edges in E‘.

Input:

The first line contains a single integer t (1 <= t <= 20), the number of test cases. Each case represents a graph. It begins with a line containing two integers n and m (1 <= n <= 100), the number of nodes and edges. Each of the following m lines contains a triple (xi, yi, wi), indicating that xi and yi are connected by an edge with weight = wi. For any two nodes, there is at most one edge connecting them.

Output:

For each input, if the MST is unique, print the total cost of it, or otherwise print the string ‘Not Unique!‘.

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!

題意:

判斷最小生成樹是否唯一,如果是就輸出最小生成樹的邊權和。

題解:

對於權值相同的邊,先把不能加入的邊去除掉,然後把能加的邊都加進圖中,如果還剩有邊,那麽說明最小生成樹不是唯一的。

代碼如下:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <queue>
using namespace std;
typedef long long ll;
const int N = 105;
int t,n,m;
struct Edge{
    int u,v,w;
    bool operator < (const Edge &A)const{
        return w<A.w;
    }
}e[N*N];
int f[N];
int find(int x){
    return f[x]==x?f[x]:f[x]=find(f[x]);
}
int Kruskal(){
    int ans=0,cnt,j;
    for(int i=0;i<=n+1;i++) f[i]=i;
    for(int i=1;i<=m;i++){
        j=i;cnt=0;
        while(e[i].w==e[j].w && j<=m) j++,cnt++;
        for(int k=i;k<j;k++){
            int fx=find(e[k].u),fy=find(e[k].v);
            if(fx==fy) cnt--;
        }
        for(int k=i;k<j;k++){
            int fx=find(e[k].u),fy=find(e[k].v);
            if(fx!=fy){
                f[fx]=fy;
                ans+=e[i].w;
                cnt--;
            }
        }
        if(cnt>0) return -1;
    }
    return ans ;
}
int main(){
    cin>>t;
    while(t--){
        scanf("%d%d",&n,&m);
        for(int i=1;i<=m;i++){
            int u,v,w;
            scanf("%d%d%d",&u,&v,&w);
            e[i].u=u;e[i].v=v;e[i].w=w;
        }
        sort(e+1,e+m+1);
        int ans = Kruskal();
        if(ans==-1) puts("Not Unique!");
        else printf("%d\n",ans);
    }
    return 0;
}

POJ1679:The Unique MST(最小生成樹)