染色判断二分图!!偶环必定是二分图!!奇环必定不是!!
思路:邻接表建图
从某一点u作为父类开始染色
1 如果发现u与v颜色相同 那么flag = false 即该图不是二分图。
2 如果v并未染色 那么将其染成相反的颜色 再以v作为父节点找相邻的点染色
3 如果u与v颜色相反 那么再去寻找u相邻的其他边
注意!如果是连通图 那么一次dfs即可 如HDU3478
AC代码:
题意不用判断是否为连通图。一次dfs即可
#include<iostream>
#include<vector>
#include<cstring>
#include<cstdio>
using namespace std;
vector<int>G[500005];
bool flag;
int n, m;
int vis[500005];
void dfs(int x, int col)
{
vis[x] = col;
for(int i = 0; i < G[x].size(); i++)
{
int t = G[x][i];
if(vis[x] == vis[t])
flag = true;
else if(vis[t] == -1)
dfs(t, !col);
}
}
void init(int n)
{
memset(vis, -1, sizeof vis);
for(int i = 0; i < n ; i++ )
{
G[i].clear();
}
}
int main()
{
int t;
cin >> t;
int cnt = 0;
while(t--)
{
int n, m, s;
scanf("%d %d %d", &n, &m, &s);
init(n);
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);
}
flag = false;
dfs(s, 0);
for(int i = 0; i < n; i++)
{
if(vis[i] == -1)
{
flag = false;
break;
}
}
printf("Case %d: ", ++cnt);
if(flag)
cout << "YES" << endl;
else cout << "NO" << endl;
}
return 0;
}
需要判断
如cf688c
n次dfs。
#include<iostream>
#include<vector>
#include<cstring>
#include<cstdio>
#include<set>
using namespace std;
vector<int>G[500005];
vector<int>s[2];
bool flag;
int book[500005];
int n, m;
int vis[500005];
bool dfs(int x, int col)
{
vis[x] = col;
if(col == 0)
s[0].push_back(x);
else s[1].push_back(x);
for(int i = 0; i < G[x].size(); i++)
{
int t = G[x][i];
if(vis[x] == vis[t])
return false;
else if(vis[t] == -1)
{
if(!dfs(t, !col))
return false;
}
}
return true;
}
void init(int n)
{
memset(vis, -1, sizeof vis);
for(int i = 1; i <= n ; i++ )
{
G[i].clear();
}
}
int main()
{
int cnt = 0;
scanf("%d %d", &n, &m);
init(n);
int u, v;
for(int i = 1; i <= m; i++)
{
scanf("%d %d", &u, &v);
G[u].push_back(v);
G[v].push_back(u);
book[u] = 1;
book[v] = 1;
}
flag = true;
for(int i = 1; i <= n; i++)
{
if(book[i] && vis[i] == -1)
{
if(dfs(i,1))
{
continue;
}
else
{
cout << -1 << endl;
return 0;
}
}
}
cout << s[0].size() << endl;
for(int i = 0;i < s[0].size();i++)
cout << s[0][i] << " ";
cout << endl;
cout << s[1].size() << endl;
for(int i = 0;i < s[1].size();i++)
cout << s[1][i] << " ";
cout << endl;
return 0;
}