POJ-1679 El árbol de expansión subpequeño de MST único

Enlace de tema

POJ-1679

Título

Pregunte si el árbol de expansión mínimo es único

Ideas

Encuentre el segundo árbol de expansión más pequeño y vea si es el mismo que el peso mínimo del árbol de expansión

En términos generales, es un problema de plantilla. No aprendí el árbol de expansión pequeño antes de escribir. Pensé en una forma sencilla.

Enumere los bordes de cada árbol de expansión mínimo, elimine los bordes y busque el árbol de expansión mínimo nuevamente, y compare los pesos. Sin embargo, las deficiencias son obvias y la complejidad es grande, y es necesario juzgar si la imagen está conectada cada vez que se elimina.

Después de aprender el algoritmo del siguiente árbol de expansión pequeño, la idea general es enumerar los bordes que no están en el árbol de expansión mínimo. Después de agregar el árbol de expansión mínimo, se formará un bucle. Elimine el borde más grande del bucle y compare las respuestas.

Código

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

Supongo que te gusta

Origin blog.csdn.net/TheSunspot/article/details/108104970
Recomendado
Clasificación