二分图判定:交叉染色

二分图判定方法:交叉染色

牛客二分图判定

#include <bits/stdc++.h>
using namespace std;
int const N = 1e5 + 10;
int n,m;
vector<int>G[N];
int color[N];
bool dfs(int u,int c){
    color[u] = c;
    for(int i=0;i<G[u].size();i++){
        int v = G[u][i];
        if(color[v] == c)   return false;
        if(color[v] == 0 && !dfs(v,-c)) return false;
    }
    return true;
}
bool solve(){
    for(int i=1;i<=n;i++){
        if(!color[i])
            if(!dfs(i,1)) return false;
    }
    return true;
}
int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++){
        int u,v;
        scanf("%d%d",&u,&v);
        G[u].push_back(v);
        G[v].push_back(u);
    }
    if(solve()) printf("Yes\n");
    else    printf("No\n");
    return 0;
}

HDU4751

题解:

  • 题目意思是单方面认识,团队里要相互认识。
  • 把不认识的两个人用一条线相连。则相邻的两个人染色应该不一样。如果dfs过程中,有两个相邻的人染色相同,那么就矛盾。

代码:

#include <bits/stdc++.h>
using namespace std;
int const N = 100 + 10;
int n,color[N],tmp;
bool know[N][N],G[N][N];
bool dfs(int u,int c){
	color[u] = c;
	for(int i=1;i<=n;i++){
		if(i != u && G[u][i]){
			if(color[i] == c)	return false;
			if(color[i] == 0 && !dfs(i,-c))	return false;
		}
	}
	return true;
}	
bool solve(){
	memset(color,0,sizeof(color));
	for(int i=1;i<=n;i++)
		if(!color[i])  //不同的连通分块
			if(!dfs(i,1))	return false;
	return true;
}
int main(){	   //二分图判定,染色
	while(~scanf("%d",&n)){
		memset(know,false,sizeof(know));
		memset(G,false,sizeof(G));
		for(int i=1;i<=n;i++)
			while(scanf("%d",&tmp) && tmp)
				know[i][tmp] = true;
		for(int i=1;i<=n;i++)
			for(int j=1;j<=n;j++)
				if(!know[i][j] || !know[j][i])	G[j][i] = G[i][j] = true;    //只要有一方不认识,就不连
		if(solve())	printf("YES\n");
		else	printf("NO\n");
	}
	return 0;
}

HDU2444

题解:

  • 这一题和上一题本质是一样,问的不一样。此题要求分成两组,每一组内的人互相不认识,所以不用取补图了。认识的人连线即可。

代码:

#include <bits/stdc++.h>
using namespace std;
int const N = 200 + 10;
int n,m,s,t;
int mp[N][N],vis[N],linker[N],color[N];
bool dfs(int u,int c){
	color[u] = c;
	for(int i=1;i<=n;i++){
		if(mp[u][i]){
			if(color[i] == c)	return false;	
			if(color[i] == 0 && !dfs(i,-c))	return false;	
		}
	}
	return true;
}
bool Judge(){
	memset(color,0,sizeof(color));
	for(int i=1;i<=n;i++){
		if(!color[i])
			if(!dfs(i,1))	return false;
	}
	return true;
}
bool dfs(int u){
	for(int i=1;i<=n;i++){
		if(vis[i] || !mp[u][i])	continue;
		vis[i] = true;
		if(linker[i] == -1 || dfs(linker[i])){
			linker[i] = u;
			return	true;
		}
	}
	return false;
}
int hunganry(){
	int res = 0;
	memset(linker,-1,sizeof(linker));
	for(int i=1;i<=n;i++){
		memset(vis,0,sizeof(vis));
		if(dfs(i))	res++;
	}
	return res;
}
int main(){
	while(~scanf("%d%d",&n,&m)){
		memset(mp,false,sizeof(mp));
		for(int i=1;i<=m;i++){
			scanf("%d%d",&s,&t);
			mp[s][t] = mp[t][s] = true;
		}
		if(!Judge())	printf("No\n");
		else{
			printf("%d\n",hunganry()/2);
		}
	}
	return 0;
}

 

posted @ 2019-03-01 14:27  月光下の魔术师  阅读(8)  评论(0)    收藏  举报