The Unique MST
题目链接:POJ - 1679题意:判断图的最小生成树是不是唯一的;
先求出最小生成树, 然后枚举去掉最小生成树的一边, 再求一边最小生成树;
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <queue>
using namespace std;
const long long INF = 0x3f3f3f3f;
const int maxn=50010;
int n, m;
struct node{
int v, w, u, id;
}edge;
bool cmp(node a, node b){
return a.w<b.w;
}
vector<node> vec;
int pre[110];
void init(){
for(int i=0; i<=n; i++){
pre[i]=i;
}
}
int find(int x){
return pre[x]==x?pre[x]:pre[x]=find(pre[x]);
}
int Union(int x, int y){
int fx=find(x), fy=find(y);
if(fx==fy) return 0;
pre[fx]=fy;
return 1;
}
vector<node> st, rt;
int ok(node a, node b){
if(a.v==b.v&&a.u==b.u||a.v==b.u&&a.u==b.v){
if(a.w<=b.w) return 1;
}
return 0;
}
void Kruskal(){
int sum=0;
st.clear();
int cnt=0;
while(cnt<vec.size()){
if(st.size()==n-1) break;
if(Union(vec[cnt].u, vec[cnt].v)){
st.push_back(vec[cnt]);
sum+=vec[cnt].w;
}
cnt++;
}
int temp;
for(int i=0; i<st.size(); i++){
temp=0;
init();
cnt=0;
rt.clear();
while(cnt<vec.size()){
if(rt.size()==n-1) break;
if(vec[cnt].id==st[i].id){
cnt++;
continue;
}
if(Union(vec[cnt].u, vec[cnt].v)){
temp+=vec[cnt].w;
rt.push_back(vec[cnt]);
}
cnt++;
}
if(rt.size()==n-1&&sum==temp){
printf("Not Unique!\n");
return;
}
}
printf("%d\n", sum);
return;
}
int main(){
int t;
scanf("%d", &t);
while(t--){
scanf("%d%d", &n, &m);
init();
vec.clear();
for(int i=0; i<m; i++){
scanf("%d%d%d", &edge.u, &edge.v, &edge.w);
edge.id=i;
vec.push_back(edge);
}
sort(vec.begin(), vec.end(), cmp);
Kruskal();
}
return 0;
}