非次小生成树做法:
也可以标记最小生成树的边
然后删边 看sum值是否等与最小值
注意 删边可能变成森林
但是耗时较多:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <limits.h>
#include <malloc.h>
#include <ctype.h>
#include <math.h>
#include <string>
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
const int maxn =1000+5;
const int maxe = 15000+5;
int father[maxn],n,m;
int find(int x)
{
if(father[x]!=x)
father[x]=find(father[x]);
return father[x];
}
void merge(int a,int b)
{
int fx,fy;
fx=find(a);
fy=find(b);
if(fx!=fy)
father[fx]=fy;
}
struct node
{
int from,to,val;
bool select;
} edge[maxe];
bool cmp(node a,node b)
{
if(a.val!=b.val)
return a.val<b.val;
if(a.from!=b.from)
return a.from<b.from;
return a.to<b.to;
}
int kruskal(int t)
{
int k=0;
int i,x,y;
int ans=0;
for(i=1; i<=n; i++)
{
father[i]=i;
}
sort(edge,edge+m,cmp);
for(i=0; i<m; i++)
{
if(k==n-1) break;
if(edge[i].val<0) continue;
if(i==t) continue;
x=find(edge[i].from);
y=find(edge[i].to);
if(x!=y)
{
merge(x,y);
k++;
ans+=edge[i].val;
if(t==-1)
edge[i].select=true;
}
}
return ans;
}
void init()
{
memset(edge,0,sizeof(edge));
}
int main()
{
// freopen("in.txt","r",stdin);
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
init();
for(int i=0; i<m; i++)
{
scanf("%d%d%d",&edge[i].from,&edge[i].to,&edge[i].val);
}
int ans=kruskal(-1);
int flag=0;
for(int i=0; i<m; i++)
{
if(edge[i].select)//
{
int num=0,a=kruskal(i);
for(int j=1; j<=n; j++)
{
if(father[j]==j)
num++;
}
if(num>1)
continue;
if(ans==a)
flag=1;
}
}
if(flag)
{
printf("Not Unique!\n");
}
else printf("%d\n",ans);
}
return 0;
}
次小生成树:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <limits.h>
#include <malloc.h>
#include <ctype.h>
#include <math.h>
#include <string>
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
const int maxn =1000+5;
const int maxe = 15000+5;
int father[maxn],n,m;
int length[maxn][maxn],head[maxn],end[maxn];
int find(int x)
{
if(father[x]!=x)
father[x]=find(father[x]);
return father[x];
}
void merge(int a,int b)
{
int fx,fy;
fx=find(a);
fy=find(b);
if(fx!=fy)
father[fx]=fy;
}
struct node
{
int from,to,val;
bool select;
} edge[maxe];
struct node1
{
int to,next;
}link[maxn];
bool cmp(node a,node b)
{
if(a.val!=b.val)
return a.val<b.val;
if(a.from!=b.from)
return a.from<b.from;
return a.to<b.to;
}
int maxx;
void kruskal(int t)
{
for(int i=0;i<=n;i++)
{
link[i].to=i+1;
link[i].next=head[i+1];
end[i+1]=i;
head[i+1]=i;
}
int k=0;
int x,y;
int ans=0;
for(int i=1; i<=n; i++)
{
father[i]=i;
}
sort(edge,edge+m,cmp);
for(int i=0; i<m; i++)
{
if(k==n-1) break;
if(edge[i].val<0) continue;
// if(i==t) continue;
x=find(edge[i].from);
y=find(edge[i].to);
if(x!=y)
{
for(int j=head[x]; j!=-1; j=link[j].next)
{
for(int k=head[y]; k!=-1; k=link[k].next)
{
length[link[j].to][link[k].to]=length[link[k].to][link[j].to]=edge[i].val;
}
}
link[end[y]].next=head[x];
end[y]=end[x];
merge(x,y);
k++;
edge[i].select=true;
}
}
}
void init()
{
memset(edge,0,sizeof(edge));
memset(head,-1,sizeof(head));
}
int main()
{
// freopen("in.txt","r",stdin);
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
init();
for(int i=0; i<m; i++)
{
scanf("%d%d%d",&edge[i].from,&edge[i].to,&edge[i].val);
// // edge[i+m]=edge[i];
// edge[i+m].from=edge[i].to;
// edge[i+m].to=edge[i].from;
}
kruskal(1);
int mst=0;
for(int i=0;i<m;i++)
{
if(edge[i].select)
mst+=edge[i].val;
}
int secmst=INT_MAX;
for(int i=0;i<m;i++)
{
if(!edge[i].select)
secmst=min(secmst,mst+edge[i].val-length[edge[i].from][edge[i].to]);
}
if(secmst==mst)
{
printf("Not Unique!\n");
}
else printf("%d\n",mst);
}
return 0;
}