算法竞赛——进阶指南——acwing257. 关押罪犯 二分图解法

之前写过带权并查集解法。

这次是二分图:

二分冲突值。

check时:

把所有冲突值大于mid的每对囚犯连接,即连边。

判断这个的每个联通块能否构成二分图。

能就可以分到2个监狱里。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define  pb push_back
const int M = 1e5+7;
const int N =2e4+7;
vector<int>G[N];
int n,m;
struct node{
	int c,u,v;
}p[M];
int col[N];
bool f;
void dfs(int x,int tp)
{
	if(!f)return ;
	col[x]=tp;
	for(auto y:G[x])
	{
		if(!col[y])dfs(y,3-tp);
		else if(col[y]==col[x])f=false;
	}
}
bool ck(int x)//能否满足  冲突值小于等于x 
{
	for(int i=1;i<=n;i++)G[i].clear();
	for(int i=1;i<=m;i++)if(p[i].c>x)G[p[i].u].pb(p[i].v),G[p[i].v].pb(p[i].u);
	memset(col,0,sizeof(col));
	f=true;
	for(int i=1;i<=n;i++)
	{
		if(col[i])continue;
		dfs(i,1);
		if(!f)return false;
	}
	return true;
}
int main()
{
	ios::sync_with_stdio(false);
  	cin.tie(0);
  	
  	cin>>n>>m;
  	for(int i=1;i<=m;i++)
  		cin>>p[i].u>>p[i].v>>p[i].c;
  	int l=0,r=1e9+7,ans=0;
  	while(l<=r)
  	{
  		int m=(l+r)/2;
  		if(ck(m))ans=m,r=m-1;
  		else l=m+1;
	}
	cout<<ans<<endl;
	return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值