题目链接:https://www.acwing.com/problem/content/description/862/
时/空限制:1s / 64MB
题目描述
给定一个n个点m条边的无向图,图中可能存在重边和自环。
请你判断这个图是否是二分图。
输入格式
第一行包含两个整数n和m。
接下来m行,每行包含两个整数u和v,表示点u和点v之间存在一条边。
输出格式
如果给定图是二分图,则输出“Yes”,否则输出“No”。
数据范围
1≤n,m≤10^5
输入样例
4 4
1 3
1 4
2 3
2 4
输出样例
Yes
解题思路
题意:判断一个无向图是不是二分图。
思路:从其中一个点开始,将跟它邻接的点染成与其不同的颜色,最后如果邻接的点有相同颜色,则说明不是二分图,每次用DFS遍历即可。
Accepted Code:
/*
* @Author: lzyws739307453
* @Language: C++
*/
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1e5 + 5;
const int MAXM = 1e5 + 5;
const int inf = 0x3f3f3f3f;
struct AddTab {
int u, v;
AddTab() {}
AddTab(int u, int v) : u(u), v(v) {}
}e[MAXM << 1];
int f[MAXN], Col[MAXN], Adj = 0;
void Add_Adj(int u, int v) {
e[++Adj] = AddTab(f[u], v);
f[u] = Adj;
}
bool DFS(int u, int fa, int C) {
Col[u] = C;
for (int i = f[u]; ~i; i = e[i].u) {
int v = e[i].v;
if (v != fa) {
if (~Col[v]) {
if (!(Col[v] != C))
return false;
}
else {
if (!DFS(v, u, !C))
return false;
}
}
}
return true;
}
bool Check(int n) {
memset(Col, -1, sizeof(Col));
for (int i = 1; i <= n; i++)
if (!~Col[i] && !DFS(i, -1, 0))
return false;
return true;
}
int main() {
int n, m;
scanf("%d%d", &n, &m);
memset(f, -1, sizeof(f));
for (int i = 0; i < m; i++) {
int u, v;
scanf("%d%d", &u, &v);
Add_Adj(u, v);
Add_Adj(v, u);
}
if (Check(n))
printf("Yes\n");
else printf("No\n");
return 0;
}