并查集

洛谷算法题解析

板板 洛谷P1111 修复公路

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm> 
using namespace std;
int n,m,fl,fa[1000000];
struct dro{
	int a;
	int b;
	int tim;
}po[1000000];
int comp(dro p,dro q) {
	return p.tim<q.tim;
}
int find(int d) {
	if(fa[d]==d) return fa[d];
	fa[d]=find(fa[d]);
	return fa[d];
}
int main() {
	int i,j,k,x,y,t; 
	cin>>n>>m;
	for(i=1;i<=n;i++) {
		fa[i]=i;
	}
	for(i=1;i<=m;i++) {
		scanf("%d%d%d",&x,&y,&t);
		po[i].a=x;
		po[i].b=y;
		po[i].tim=t;
	}
	sort(po,po+m+1,comp);
	for(i=1;i<=m;i++) {
		k=fa[find(po[i].a)]=find(po[i].b);
		fl=1;
		for(j=1;j<=n;j++) 
			if(find(j)!=k){
				fl=0;
				break;
			}
		if(fl==1) {
			cout<<po[i].tim<<endl;
			break;
		}
	}
	if(fl==0) cout<<-1;
	return 0;
}

两倍存 洛谷P1525 关押罪犯

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
int cnt,fa[100009],em[100009],fl;
struct deliver{
	int to;
	int w;
	int fr;
}eg[100060];
void add(int a,int b,int c) {
	cnt++;
	eg[cnt].to=b;	
	eg[cnt].fr=a;
	eg[cnt].w=c;
}
int comp(deliver p,deliver q) {
	return p.w>q.w;
}
int find(int a) {
	if(fa[a]==a) return fa[a];
	fa[a]=find(fa[a]);
	return fa[a];
}
void rp(int a,int b) {
	fa[find(a)]=find(b);
}
int main() {
	int i,j,k,a,b,c;
	int n,m;
	cin>>n>>m;
	for(i=1;i<=2*n;i++) 
		fa[i]=i;
	for(i=1;i<=m;i++) {
		scanf("%d%d%d",&a,&b,&c);
		add(a,b,c);
	}
	sort(eg+1,eg+m+1,comp);
	for(i=1;i<=m;i++) {
		int u=eg[i].fr;
        int v=eg[i].to;
        if(find(u)==find(v)) {
        	cout<<eg[i].w;
        	fl=1;
        	break;
		}
		fa[find(u+n)]=find(v);
		fa[find(v+n)]=find(u);
	}
	if(fl==0) cout<<0;
	return 0;
}

三倍存 洛谷P2024 食物链

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdio>
using namespace std;
int n,k,ans,fa[1000000];
int find(int j) {
	if(fa[j]==j) return fa[j];
	fa[j]=find(fa[j]);
	return fa[j];
}
void an(int a,int b) {
	fa[find(a)]=find(b);
}
int main() {
	int i,j,a,b,c; 
	cin>>n>>k;
	for(i=1;i<=n*3;i++)
	    fa[i]=i;
	for(i=1;i<=k;i++) {
		scanf("%d%d%d",&c,&a,&b);
		if(a>n||b>n)
			ans++;
			else {
			 	if(c==1) {
			 		if(find(a+n)==find(b)||find(a+2*n)==find(b)) ans++;
			 		  else {
			 		  	    an(a,b);
			 		  	    an(a+n,b+n);
			 		  	    an(a+2*n,b+2*n);
					   }
				 }
				 if(c==2) {
				 	if(find(a)==find(b)||find(a+2*n)==find(b)) ans++;
				 	  else {
				 	  	an(a,b+2*n);
				 	  	an(a+n,b);
				 	  	an(a+2*n,b+n);
					   }
				 }
				 
			}
	        
	}
	cout<<ans;
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值