洛谷题解P1525 [NOIP2010 提高组] 关押罪犯 (并查集)

洛谷题解P1525 [NOIP2010 提高组] 关押罪犯 (并查集)

这一题是此蒟蒻的第一题并查集
题目很简单看不懂的回去看

#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<queue>
#include<cstring>
using namespace std;
typedef long long ll;
const int inf=1e9+7;
inline int read() {
    
    
	int p=0,f=1;
	char c=getchar();
	while(c<'0'||c>'9') {
    
    
		if(c=='-')f=-1;
		c=getchar();
	}
	while(c>='0'&&c<='9') {
    
    
		p=p*10+c-'0';
		c=getchar();
	}
	return f*p;
}
const int maxn=20009;
const int maxm=200019;
struct Edge {
    
     //定义边:起点nex,终点to,边权w
	int from,to,w;
} p[maxm];
int n,m,fa[maxn],Enemy[maxn];
//fa[i]是i的父亲(并查集),Enemy[i]是i的敌人(不能在同一组)
int find(int k) {
    
     //并查集找父亲
	if(fa[k]==k)return k;
	else return fa[k]=find(fa[k]);
}
bool cmp(Edge x,Edge y) {
    
    
	return x.w>y.w;
}
int main() {
    
    
	n=read(),m=read();
	for(int i=1; i<=m; i++) {
    
    
		p[i].from=read();
		p[i].to=read();
		p[i].w=read();
	}
	for(int i=1; i<=n; i++) fa[i]=i;
	sort(p+1,p+1+m,cmp);//按怒气值从大到小排序
	//合并罪犯important!!!
	for(int i=1; i<=m; i++) {
    
    
		int t1=find(p[i].from);
		int t2=find(p[i].to);
		if(t1==t2) {
    
     //出现矛盾
			printf("%d",p[i].w);
			return 0;
		}
		//其余的就把敌人的敌人与自己分到一组
		if(!Enemy[p[i].from])//no enemies
			Enemy[p[i].from]=p[i].to;//then they can be room mates
		else fa[find(Enemy[p[i].from])]=find(p[i].to);//have enemies ,then change the father (get another room mate)
		if(!Enemy[p[i].to])//same thing
			Enemy[p[i].to]=p[i].from;
		else fa[find(Enemy[p[i].to])]=find(p[i].from);
	}
	printf("0");//no enemies
	return 0;
}//由于此人是SB所以中英结合将就看吧
//有问题问我

猜你喜欢

转载自blog.csdn.net/weixin_45446715/article/details/120107771