1. 程式人生 > >【模板·次小生成樹】 The Unique MST

【模板·次小生成樹】 The Unique MST

程式碼:

#include<cstdio>
#include<vector>
#include<cstring>
#include<algorithm>
using namespace std;

#define maxn 100
#define maxm 10000
#define read(x) scanf("%d",&x)

struct Edge{
	int x,y,z;
	Edge(){}
	Edge(int xx,int yy,int zz) {
		x=xx,y=yy,z=zz;
	}
	bool operator < (const
Edge& oth) const { return z<oth.z; } }; int n,m; Edge e[maxm+5]; int fa[maxn+5]; bool intree[maxm+5]; int find(int x) { if(fa[x]) return fa[x]=find(fa[x]); return x; } vector<Edge> g[maxn+5]; int kruskal() { int s=0; sort(e+1,e+m+1); for(int i=1;i<=m;i++) { int fa1=find
(e[i].x),fa2=find(e[i].y); if(fa1==fa2) continue; fa[fa1]=fa2; s+=e[i].z; intree[i]=true; g[e[i].x].push_back(e[i]); g[e[i].y].push_back(Edge(e[i].y,e[i].x,e[i].z)); } return s; } bool isuse[maxm+5]; int d[maxn+5][maxn+5]; void init() { memset(d,0,sizeof(d)); memset(isuse,0,sizeof(isuse)
); memset(intree,0,sizeof(intree)); memset(fa,0,sizeof(fa)); for(int i=1;i<=n;i++) g[i].clear(); } void dfs(int x,int fa,int y) { for(int i=1;i<=n;i++) { if(isuse[i]) d[x][i]=d[i][x]=max(d[fa][i],y); } isuse[x]=true; for(int i=0;i<g[x].size();i++) { if(isuse[g[x][i].y]) continue; dfs(g[x][i].y,x,g[x][i].z); } } int sec() { int ans=1e9; for(int i=1;i<=m;i++) { if(!intree[i]) { ans=min(ans,-d[e[i].x][e[i].y]+e[i].z); } } return ans; } int main() { int T; read(T); while(T--) { read(n),read(m); init(); for(int i=1;i<=m;i++) { int x,y,z; read(x),read(y),read(z); e[i]=Edge(x,y,z); } int ans=kruskal(); dfs(1,0,0); int ans2=sec()+ans; if(ans==ans2) printf("Not Unique!\n"); else printf("%d\n",ans); } return 0; }