题意大概是说判断最小生成树是否是唯一的,如果唯一的就输出最小权值,否则输出 No Unique!
网上的思路是:先求最小生成树,并且把边记录下来,然后将最小生成树的各个边删掉,判断是否还能生成一和个原来权值一样的树,如果可以就不唯一,否则唯一。
#include<iostream>
#include<algorithm>
#include<stdlib.h>
#include<string.h>
#include<string>
#include<vector>
#include<queue>
#include<list>
using namespace std;
typedef long long lld;
typedef unsigned int ud;
#define Inf INT_MAX//int最大
#define Min(x,y) (x)<(y)?(x):(y)
#define Max(x,y) (x)>(y)?(x):(y)
#define PQ priority_queue
#define Q queue
#define N 102
#define M 10002
struct Node
{
int u,v;
int w;
}edge[M];
int parent[N];
int n,m;
int MST_edge[N];
void InitParent()
{
for(int i=1;i<=n;i++)
parent[i]=-1;
}
int find(int x)
{
return parent[x]<0 ? x : find(parent[x]);
}
void merge(int r1,int r2)
{
if(parent[r1]>parent[r2])
{
parent[r1]=r2;
//parent[r2]+=parent[r1];
}
else
{
parent[r2]=r1;
//parent[r1]+=parent[r2];
}
}
bool cmp(Node n1,Node n2)
{
return n1.w<n2.w;
}
void Kruskal()
{
sort(edge+1,edge+m+1,cmp);
int res=0;
InitParent();
int k=1;
for(int i=1;i<=m;i++)
{
if(k>n-1)
break;
int u=find(edge[i].u);
int v=find(edge[i].v);
if(u!=v)
{
res+=edge[i].w;
merge(u,v);
//加入生成树的边
MST_edge[k++]=i;
}
}
for(int i=1;i<=n-1;i++)
{
int sumW=0;
int mst_n=0;
InitParent();
for(int j=1;j<=m;j++)
{
if(j==MST_edge[i])
continue;
int u=find(edge[j].u);
int v=find(edge[j].v);
if(u!=v)
{
sumW+=edge[j].w;
mst_n++;
merge(u,v);
}
}
if(mst_n!=n-1)
continue;
if(sumW==res)
{
printf("Not Unique!\n");
return ;
}
}
printf("%d\n",res);
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)
{
//int u,v,w;
scanf("%d%d%d",&edge[i].u,&edge[i].v,&edge[i].w);
}
Kruskal();
}
return 0;
}