http://bailian.openjudge.cn/practice/1679
题解:次小生成树。
代码:
#include <iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn = 105;
const int maxm= 10005;
int p[maxn];
int finde(int x){
if(p[x]==x)return x;
return p[x]=finde(p[x]);
}
bool issame(int x,int y){
x=finde(x);
y=finde(y);
return x==y;
}
void join(int x,int y){
x=finde(x);
y=finde(y);
p[x]=y;
}
struct node{
int a,b,w;
bool select;
}e[maxm];
bool cmp(node a,node b){
return a.w<b.w;
}
struct node1{
int to,next;
};
node1 link[maxn];
int il;
int head[maxn];
int iend[maxn];
int length[maxn][maxn];
int n,m;
void kruskal(){
int k=0;
int i,x,y;
int w,v;
for(il=0;il<=n;il++){
link[il].to=il+1;
link[il].next=head[il+1];
iend[il+1]=il;
head[il+1]=il;
}
sort(e,e+m,cmp);
for(i=0;i<m;i++){
if(k==n-1)break;
if(e[i].w<0)continue;
x=finde(e[i].a);
y=finde(e[i].b);
if(x!=y){
for(w=head[x];w!=-1;w=link[w].next){
for(v=head[y];v!=-1;v=link[v].next){
length[link[w].to][link[v].to]=length[link[v].to][link[w].to]=e[i].w;
}
}
link[iend[y]].next=head[x];
iend[y]=iend[x];
join(x,y);
k++;
e[i].select=true;
}
}
return ;
}
void init(){
int i;
for(i=1;i<=n;i++)p[i]=i;
memset(head,-1,sizeof(head));
memset(length,0,sizeof(length));
//memset(e,0,sizeof(e));
}
int main()
{
int t,i;
scanf("%d",&t);
while(t--){
scanf("%d%d",&n,&m);
init();
for(i=0;i<m;i++){scanf("%d%d%d",&e[i].a,&e[i].b,&e[i].w);e[i].select=false;}
kruskal();
int mst=0;
for(i=0;i<m;i++)if(e[i].select)mst+=e[i].w;
int secmst=0x3f3f3f3f;
for(i=0;i<m;i++){
if(!e[i].select){
secmst=min(secmst,mst+e[i].w-length[e[i].a][e[i].b]);
}
}
if(mst!=secmst)printf("%d\n",mst);
else printf("Not Unique!\n");
}
//cout << "Hello world!" << endl;
return 0;
}