Acwing 860. 染色法判定二分图
题目描述
给定一个 n 个点 m条边的无向图,图中可能存在重边和自环。
请你判断这个图是否是二分图。
输入格式
第一行包含两个整数 n 和 m。
接下来 m
行,每行包含两个整数 u 和 v,表示点 u 和点 v 之间存在一条边。
输出格式
如果给定图是二分图,则输出 Yes,否则输出 No。
数据范围
1≤n,m≤105
思路
深度搜素,遍历每个点,没有染色就进行染色,深度搜素就是将这个点邻接的所有点都染色,染成不同颜色。然后邻接的所有点也同样操作,将其邻接的所有的点染色
如果染色过程发现了邻接的点颜色一样就代表不是二分图。
这样一个连通图中的所有的点都能染上色。如果不是一个连通图,只要遍历了所有点就行。
代码
#include<iostream>
#include<cstring>
using namespace std;
int n , m;
const int N =100010;
int e[2*N],ne[2*N],h[N],idx;
void add(int a, int b)
{
e[idx] = b, ne[idx] = h[a], h[a] = idx ++;
}
int color [N];
bool dfs(int d , int c)
{
color[d]= c;
for(int i = h[d] ; i != -1 ; i = ne[i])
{
int t = e[i];
if(!color[t])
{
if(!dfs(t,3-c)) return false;
}
else if(color[t] == c) return false ;
}
return true ;
}
int main()
{
memset(h,-1,sizeof h);
scanf("%d%d",&n,&m);
while(m--)
{
int a, b;
scanf("%d%d",&a,&b);
add(a,b),add(b,a);
}
bool flag = true;
for(int i = 1 ;i <= n ; ++ i)
{
if(!color[i])
{
if(!dfs(i,1))
{
flag = false;
break;
}
}
}
if(flag)
puts("Yes");
else
puts("No");
return 0;
}
puts("Yes");
else
puts("No");
return 0;
}