洛谷题解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所以中英结合将就看吧
//有问题问我