二分图判定问题
给定一个具有n个定点的图。要给图上每个定点染色,并且要是相邻的顶点颜色不同。问是否能最多用2种颜色进行染色?题目保证没有重边和自环。(n为点数,e为边数)
限制条件:(1<=n<=1e3)
输入:
n=3,e=3
0 1
0 2
1 2
输出:
No
n=4,e=4
0 1
0 3
1 2
2 3
输出:
Yes
这是二分图的模板题。
思路:
如果使用两种颜色,那么确定一个顶点后,与他相邻的顶点也就确定了。因此任意选择一个顶点出发,以此确定相邻顶点的颜色,如果当这个点相邻顶点的颜色和自己相同,则不能构成二分图,return false。下面用dfs来实现。
//
// Created by luozujian on 17-10-11.
//
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<vector>
using namespace std;
const int maxv = 1e3+5;
int E,V;
vector<int>G[maxv];
int color[maxv];
bool dfs(int v,int c)
{
color[v] = c;
for(int i=0;i<G[v].size();i++)
{
//如果相邻顶点的颜色相同,则返回false
if(color[G[v][i]] == c) return false;
//如果相邻顶点的颜色还没染过,就吧他染成-c
if(color[G[v][i]] == 0 && !dfs(G[v][i],-c)) return false;
}
return true;
}
void solve()
{
memset(color,0,sizeof(color));
for(int i=0;i<V;i++)
{
if(color[i] == 0)
{
if(!dfs(i,1))
{
printf("No\n");
return;
}
}
}
printf("Yes\n");
}
int main()
{
scanf("%d%d",&E,&V);
for(int i=0;i<E;i++)
{
int s,t;
scanf("%d%d",&s,&t);
G[s].push_back(t);
G[t].push_back(s); //二分图是无向图
}
solve();
return 0;
}
如果图是连通图,以此dfs就可以遍历所有的顶点,但是问题并没有说图是连通图,所以需要对每个顶点进行判断。