题目链接
二分答案进行判断,对于每个点,判断该点与该点所能到的点,如果两者的仇恨值大于二分的答案,则将两个点染成不同的颜色,并把该点能到的点加入到下一个要判断的点中(本着敌人的敌人就是朋友的原则,即如果与该点的仇恨值大于二分值,则染成与一开始的点相同的颜色)
#include<bits/stdc++.h>
using namespace std;
const int maxn=20007;
const int maxm=200007;
int n,m;
int cnt,head[maxn];
struct node
{
int next;
int to;
int cost;
}edge[maxm];
void add(int x,int y,int z)
{
edge[++cnt].to=y;
edge[cnt].next=head[x];
edge[cnt].cost=z;
head[x]=cnt;
edge[++cnt].to=x;
edge[cnt].next=head[y];
edge[cnt].cost=z;
head[y]=cnt;
}
bool check(int mid)
{
queue<int>q;
int p[maxn]={0};
for(int i=1;i<=n;i++)
{
if(p[i]==0)
{
q.push(i);
p[i]=1;
while(!q.empty())
{
int u=q.front();
q.pop();
for(int i=head[u];i;i=edge[i].next)
{
int v=edge[i].to;
if(edge[i].cost>mid)
{
if(p[v]&&p[v]==p[u]) return 0;
if(!p[v]) q.push(v);
if(p[u]==1) p[v]=2;
else p[v]=1;
}
}
}
}
}
return 1;
}
int main()
{
int x,y,z,l,r=0;
scanf("%d%d",&n,&m);
while(m--)
{
scanf("%d%d%d",&x,&y,&z);
add(x,y,z);
r=max(r,z);
}
while(l<r)
{
int mid=(r+l)/2;
if(check(mid))
r=mid;
else
l=mid+1;
}
printf("%d\n",l);
return 0;
}