POJ-1679 The Unique MST sub-small spanning tree

Topic link

POJ-1679

Title

Ask whether the minimum spanning tree is unique

Ideas

Find the second smallest spanning tree and see if it is the same as the minimum spanning tree weight

Generally speaking, it is a template problem. I didn’t learn the sub-small spanning tree before writing. I thought of a simple way.

Enumerate the edges of each minimum spanning tree, remove the edges and find the minimum spanning tree again, and compare the weights. However, the shortcomings are obvious, and the complexity is large, and it is necessary to judge whether the picture is connected every time it is deleted.

After learning the algorithm of the next small spanning tree, the general idea is to enumerate the edges that are not in the minimum spanning tree. After adding the minimum spanning tree, a loop will be formed. Delete the largest edge in the loop and compare the answers.

Code

#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;
	}
	

Guess you like

Origin blog.csdn.net/TheSunspot/article/details/108104970