NOIP2010 关押罪犯
题意简化
传送门
有两座监狱,n个罪犯,给定m组罪犯之间的关系,若此二人在同一监狱则会产生摩擦
求最小化最大的摩擦
$ n<=20000 m<=100000 $
题解
看到这一类似的题,按照经验
先是排一遍序
然后按照摩擦值从大到小的顺序
把每个关系都用并査集连一下
(注意连边的方向)
知道第一次连到已经连通的点时,当前边权就是答案
代码
#include<bits/stdc++.h>
using namespace std;
int n,m,en[20001],fa[20001];
struct pig{
int x,y,w;
}a[100001];
inline int cmp(pig a,pig b)
{
if(a.w>b.w)return 1;
return 0;
}
inline int father(int x)
{
if(fa[x]!=x)fa[x]=father(fa[x]);
return fa[x];
}
inline bool check(int x,int y)
{
if(father(x)==father(y))return 1;
return 0;
}
inline void merge(int x,int y)
{
x=father(fa[x]);
y=father(fa[y]);
fa[x]=y;
}
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)fa[i]=i;
for(int i=1;i<=m;i++)
cin>>a[i].x>>a[i].y>>a[i].w;
sort(a+1,a+1+m,cmp);
for(int i=1;i<=m+1;i++)
{
if(check(a[i].x,a[i].y)){
cout<<a[i].w;return 0;
}
else
{
int x=a[i].x,y=a[i].y;
if(en[x]==0)en[x]=y;
else merge(en[x],y);
if(en[y]==0)en[y]=x;
else merge(en[y],x);
}
}
cout<<0;
return 0;
}
嗯,就这样了...