Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 20787 | Accepted: 7315 |
Description
Input
Output
Sample Input
2 3 3 1 2 1 2 3 2 3 1 3 4 4 1 2 2 2 3 2 3 4 2 4 1 2
Sample Output
3 Not Unique!
这题就是求次小生成树。
#include<cstdio> #include<iostream> #include<cstring> #include<algorithm> #define Maxn 110 using namespace std; struct line{ int u,v,w; bool operator<(const line &a)const{ return w<a.w; } }p[Maxn*Maxn]; int fa[Maxn],head[Maxn],ed[Maxn],nxt[Maxn],use[Maxn*Maxn],maxcost[Maxn][Maxn]; void init(int n){ for(int i=1;i<=n;i++) fa[i]=head[i]=ed[i]=i,nxt[i]=-1; } int findset(int x){ return fa[x]==x?x:(fa[x]=findset(fa[x])); } void unionset(int a,int b){ fa[b]=a; nxt[ed[a]]=head[b]; ed[a]=ed[b]; } int kruskal(int n,int m){ init(n); int ans=0,cnt=0; for(int i=0;i<m;i++){ int a=findset(p[i].u),b=findset(p[i].v); if(a!=b){ ans+=p[i].w; for(int j=head[a];j!=-1;j=nxt[j]) for(int k=head[b];k!=-1;k=nxt[k]) maxcost[j][k]=maxcost[k][j]=p[i].w; unionset(a,b); use[i]=1; if(++cnt==n-1) break; } } return ans; } int main() { int t,n,m; scanf("%d",&t); while(t--){ scanf("%d%d",&n,&m); for(int i=0;i<m;i++) scanf("%d%d%d",&p[i].u,&p[i].v,&p[i].w); sort(p,p+n); memset(use,0,sizeof use); int ans=kruskal(n,m); bool flag=false; for(int i=0;i<m;i++) if(!use[i]&&p[i].w==maxcost[p[i].u][p[i].v]) {flag=true;break;} if(flag) puts("Not Unique!"); else printf("%d\n",ans); } return 0; }