POJ - 1679 The Unique MST 次小生成树

题目链接

POJ-1679

题意

问最小生成树是否唯一

思路

求取次小生成树,看是否和最小生成树权值一样即可

总的来说是道模板题,在写之前没学次小生成树,想的是一种朴素做法

枚举每一条最小生成树的边,去掉后重新求最小生成树,比较权值即可。但 是缺点很明显,复杂度大,每次删除还要判断图是否联通。

之后学习了一下次小生成树的算法,大概思想就是枚举不在最小生成树的边,加入最小生成树后一定会形成环路,删除掉环路中最大的边,比较答案即可。

代码

#include<cstdio>
#include<iostream>
#include<iomanip>
#include<map>
#include<string>
#include<queue>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstdlib> 
#include<vector>
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define endl "\n"
//#define int long long
using namespace std;
	typedef long long ll;
	const int maxn=80000;
	const int inf=0x3f3f3f3f;
	const ll INF=0x3f3f3f3f3f3f3f3f;
	int fa[maxn];
	vector<int>G[150];
	int dis[150][150];
	struct Edge{
    
    
		int u,v;
		int w;
		int mbl;
	}edge[maxn];
	
	void init(int n){
    
    
		for(int i=0;i<=n;i++){
    
    
			G[i].clear();
			G[i].push_back(i);
			fa[i]=i;
		}
	}	
	int find(int x){
    
    
		return x==fa[x]?x:fa[x]=find(fa[x]);
	}
	void unite(int x,int y){
    
    
		int fx=find(x),fy=find(y);
		if(fx==fy)
			return ;
		fa[fx]=fy;
		int len=G[fx].size();
		for(int i=0;i<len;i++)
			G[fy].push_back(G[fx][i]);
		return ;		
	}
	bool cmp(Edge a,Edge b){
    
    
		return a.w<b.w;
	}
	int main(){
    
    
		IOS
		int tn;
		bool bl;
		cin>>tn;
		while(tn--){
    
    
			memset(edge,0,sizeof edge);
			int n,m;
			cin>>n>>m;
			init(n);
			for(int i=1;i<=m;i++)
				cin>>edge[i].u>>edge[i].v>>edge[i].w;
			int ans=0;
			sort(edge+1,edge+1+m,cmp);
			for(int i=1;i<=m;i++){
    
    
				int u=edge[i].u,v=edge[i].v;
				int fu=find(u),fv=find(v);
				if(fu!=fv){
    
    
					edge[i].mbl=1;
					ans+=edge[i].w;
					int len1=G[fu].size(),len2=G[fv].size();
					for(int ii=0;ii<len1;ii++)
						for(int j=0;j<len2;j++)
							dis[G[fu][ii]][G[fv][j]]=dis[G[fv][j]][G[fu][ii]]=edge[i].w;
					unite(u,v);
				}
			}
			int t=inf;
			for(int i=1;i<=m;i++){
    
    
				if(edge[i].mbl)
					continue;
				t=min(t,ans+edge[i].w-dis[edge[i].u][edge[i].v]);
			}
			if(t>ans)
				cout<<ans<<endl;		
			else
				cout<<"Not Unique!"<<endl;
		}
		return 0;
	}
	

猜你喜欢

转载自blog.csdn.net/TheSunspot/article/details/108104970
今日推荐