可以将图上的所有点分成两个集合,同一集合内的点在图上没有连边。这种图称为二分图 参考博客-二分图的定义和判定
二分图证明:染色法
我们可以用两种颜色去涂一个图,使的任意相连的两个顶点颜色不相同,且任意两个结点之间最多一条边。如果发现相邻点染色成同一颜色,则这个图不是二分图。有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;
}