【洛谷 P1525】【二分】【二分图】关押罪犯
解题思路
首先两个监狱就想到了二分图
尽量使同一颜色之间的矛盾小
然后我就蒙了。。。
二分一开始是没想到了
二分枚举最大矛盾值
超过这个矛盾值的一对犯人,填上不同颜色
如果最后是一个二分图,说明这个矛盾值是大于等于答案
代码
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
struct lzf{
int x,to,q,nxt;
}f[200010];
int n,m,x,y,v,l,r,t,ans,c[20010],q[200010],head[100010];
void add(int x,int y,int v)
{
f[++t].x=x;
f[t].to=y;
f[t].q=v;
f[t].nxt=head[x];
head[x]=t;
}
bool check(int x)
{
memset(c,0,sizeof(c));
for (int i=1;i<=n;i++)
if (!c[i])
{
q[1]=i;
c[i]=1;
int h=0,ta=1;
while (h<ta)
{
h++;
for (int j=head[q[h]];j;j=f[j].nxt)
if (f[j].q>=x)
{
if (!c[f[j].to])
{
q[++ta]=f[j].to;
if (c[q[h]]==1) c[f[j].to]=2;
else c[f[j].to]=1;
}
else if (c[f[j].to]==c[q[h]]) return false;
}
}
}
return true;
}
int main()
{
scanf("%d%d",&n,&m);
for (int i=1;i<=m;i++)
{
scanf("%d%d%d",&x,&y,&v);
add(x,y,v);
add(y,x,v);
r=max(r,v);
}
while (l+1<r)
{
int mid=(l+r)/2;
if (check(mid)) r=mid;
else l=mid;
}
printf("%d",l);
return 0;
}