1,对图中每条边,扫描其他边,若存在相同权值的边,标记。
2.用kruskal算法或prim算法构造mst。
3.求得mst后,若mst不含有标记的边,则mst唯一。若有,则依次去掉标记过的边,再求mst,若求得的mst权值与原mst权值相等,即可判定该mst不唯一。
poj 1679(简单题):
http://poj.org/problem?id=1679
模板题:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=105;
struct node
{
int u,v,w;
int equal,used,del;
bool operator <(const node& b) const
{
return w<b.w;
}
}edge[N*N];
int n,m;
bool first;
int parent[N];
int weight;
void init()
{
memset(parent,-1,sizeof(parent));
}
int Find(int num)
{
int s=num;
while(parent[s]>=0)
{
s=parent[s];
}
while(num!=s)
{
int ss=parent[num];
parent[num]=s;
num=ss;
}
return s;
}
void Union(int u,int v)
{
int r1=Find(u);
int r2=Find(v);
int tmp=parent[r1]+parent[r2];
if(r1>r2)
{
parent[r1]=r2;
parent[r2]=tmp;
}
else
{
parent[r1]=tmp;
parent[r2]=r1;
}
}
void Kruskal()
{
int u,v;
int num=0;
init();
for(int i=1;i<=m;i++)
{
if(edge[i].del==1) continue;
u=edge[i].u;
v=edge[i].v;
if(Find(u)!=Find(v))
{
Union(u,v);
num++;
weight+=edge[i].w;
//cout<<weight<<endl;
if(first) edge[i].used=1;
}
if(num>=n-1) return;
}
}
int main()
{
//freopen("in.txt","r",stdin);
int Test;
cin>>Test;
while(Test--)
{
weight=0;
cin>>n>>m;
int u,v,w;
for(int i=1;i<=m;i++)
{
cin>>u>>v>>w;
edge[i].u=u;edge[i].v=v;edge[i].w=w;
edge[i].used=edge[i].del=edge[i].equal=0;
}
for(int i=1;i<m;i++)
{
for(int j=i+1;j<=m;j++)
{
if(edge[i].w==edge[j].w)
{
edge[i].equal=edge[j].equal=1;
}
}
}
sort(edge+1,edge+n+1);
first=true;
Kruskal();
first=false;
int tmp=weight;
//cout<<weight<<endl;
bool judge=false;
for(int i=1;i<=m;i++)
{
if(edge[i].equal&&edge[i].used)
{
weight=0;
edge[i].del=1;
Kruskal();
edge[i].del=false;
if(weight==tmp)
{
cout<<"Not Unique!"<<endl;
judge=true;
break;
}
}
}
if(!judge)
cout<<tmp<<endl;
}
//system("pause");
return 0;
}