二分图判定
二分图判定
http://www.nowcoder.com/questionTerminal/f4b8d0481c7b4278b9b406b636e3c7db
题解
题目难度:中等难度
知识点:图、邻接矩阵、DFS
DFS方法思路:
步骤一:构造邻接邻接矩阵G[N]
示例一点连接情况的输入:
1 2
2 3
3 4
4 1
4 5
5 2
其G[N]为:
步骤二:用color[N]表示点的着色情况,例如点2,color[2]=0表示点2未着色,color[2]=1表示点2上黑色,color[2]=-1表示点2上白色。
步骤三:采用DFS方法给点进行上色并判断是否发生冲突。
DFS方法:bool DFS(int u, int c),u表示着色点,c为该点的颜色,color[u] = c其含义是点u为c色。
A.通过G[u].size(),找到有几个点与U点相连接,通过G[u][i]取出连接点v。
B.依次判断其连接点v的着色情况:
aa..如果color[v]=c,表示u和其连接点着色冲突,因此直接返回false。
bb.如果连接点未着色即color[v]=0,那么我们将其颜色设置未-color,并且通过DFS(v, -c)判断v点与其邻接点是否冲突。如果DFS(v, -c)的返回值为false,那么存在冲突,因此DFS(u, c)直接返回false;如果不冲突,接着判断u的下一个邻接点。
cc.如果color[v]=-c,表示其邻接点已经着色,并且没有发生冲突,直接判断下一个邻接点。
C.当判断完所有邻接点(在循环过程中没有return),那么表示u与所有的邻接点未发生冲突,即return true。
步骤四:如果该图为连通图,那么我们只需要一次DFS即可判断是否可以着色。但是该题目中说明了此图可能不连通,所以在主函数中需要添加一层循环,遍历所有点。首先判断该点是否已经着色,若未着色从该点进行新一轮的DFS。
#include <iostream> #include<vector> #define N 100007 using namespace std; 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; } int main(){ cin>>n>>m; for(int i=0;i<m;i++){ int u,v; cin>>u>>v; G[u].push_back(v); G[v].push_back(u); } bool flag = true; for(int i=1;i<=n;i++){ if(color[i]==0 && !DFS(i,1)){ flag = false; break; } } cout<<(flag?"Yes":"No")<<endl; return 0; }