LGP1525-二分图判断+二分

可以将图上的所有点分成两个集合,同一集合内的点在图上没有连边。这种图称为二分图 参考博客-二分图的定义和判定

二分图证明:染色法
我们可以用两种颜色去涂一个图,使的任意相连的两个顶点颜色不相同,且任意两个结点之间最多一条边。如果发现相邻点染色成同一颜色,则这个图不是二分图。有dfs和bfs两种实现方法。

LGP1525
只用判断大于二分查找的最大权值的边(不能在一起的罪犯),(符合条件的实际是断开的)的图是否是二分图,就在这个图上找奇环

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6+10;
const int N=100010;
int head[maxn],cnt,clo[maxn];
int n,m;
struct ac{
	int v,nex,c;
}edge[maxn*2];
void addedge(int u,int v,int c){
	edge[++cnt]=(ac){v,head[u],c};
	head[u]=cnt;
}
void init(){
	memset(head,-1,sizeof head);
	cnt=0; 
}
int flag;
bool dfs(int u,int mc,int cl){
	if(flag==0)return false;
	clo[u]=cl;
	for(int i=head[u];i!=-1;i=edge[i].nex){
		int v=edge[i].v;
		int c=edge[i].c;
		if(c>mc){
			if(clo[v]==-1) dfs(v,mc,cl^1);
			else if(clo[v]==clo[u]) {
				flag=0;
				return false;
			}
		}
	}
	return true;
}
bool Judge(int m){
	flag=1;
	memset(clo,-1,sizeof clo);
	for(int i=1;i<=n&&flag;i++){
		if(clo[i]==-1)
			dfs(i,m,1);
	}
	return flag;
}
int main(){
	init();
	scanf("%d%d",&n,&m);
	long long l=0,r=0;
	for(int i=1;i<=m;i++){
		int u,v,c;
		scanf("%d%d%d",&u,&v,&c);
		addedge(u,v,c);
		addedge(v,u,c);
		if(c>r) r=c;
	}
	int m=(l+r)>>1;
	while(l<=r){
		if(Judge(m)==true){
			r=m-1;
			m=(l+r)>>1;
		}
		else {
			l=m+1;
			m=(l+r)>>1;
		}
	}
	cout<<l<<endl;
	return 0;
} 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值