您的位置:首页 > 其它

NYOJ 1015 二部图

2016-04-05 16:31 281 查看

二部图

时间限制:1000 ms | 内存限制:65535 KB
难度:1

描述
二部图又叫二分图,我们不是求它的二分图最大匹配,也不是完美匹配,也不是多重匹配,而是证明一个图是不是二部图。证明二部图可以用着色来解决,即我们可以用两种颜色去涂一个图,使的任意相连的两个顶点颜色不相同,切任意两个结点之间最多一条边。为了简化问题,我们每次都从0节点开始涂色

输入输入:

多组数据

第一行一个整数 n(n<=200) 表示 n个节点

第二行一个整数m 表示 条边

随后 m行 两个整数 u , v 表示 一条边输出如果是二部图输出 BICOLORABLE.否则输出 NOT BICOLORABLE.样例输入
330 11 22 0320 10 2

样例输出
NOT BICOLORABLE.BICOLORABLE.


分析;题意很清楚,就是让判断一个图是不是二分图,思路当然就是染色法,首先给一个顶点然色,然后与它相邻的顶点全部染相反的颜色,如果过程中发现要染的点已经染色了,而且是和现在点相同的颜色的话,那么就说明不是一个二分图。

广搜:
#include <cstdio>
#include <vector>
#include <queue>
#include <cstring>
using namespace std;

vector<int> v[205];

int n, m;
int vis[205];
int x;

void bfs()
{
memset(vis, 0, sizeof(vis));
queue<int> q;
x = 0;
vis[x] = 1;
q.push(x);
while (!q.empty()){
x = q.front();
q.pop();
for (int i = 0; i < v[x].size(); i++){
int y = v[x][i];
if (vis[y] == 0){
vis[y] = (vis[x] == 1 ? 2 : 1);
q.push(y);
}
else{
if (vis[x] == vis[y]){
printf("NOT BICOLORABLE.\n");
return;
}
}
}
}
printf("BICOLORABLE.\n");
return;
}

int main()
{
int a, b;
while (scanf("%d", &n) != EOF){
scanf("%d", &m);
for (int i = 0; i < m; i++){
scanf("%d%d", &a, &b);
v[a].push_back(b);
v[b].push_back(a);
}
bfs();
for (int i = 0; i <= n; i++)
v[i].clear();
}
return 0;
}


深搜:
#include <cstdio>
#include <vector>
#include <queue>
#include <cstring>
using namespace std;

vector<int> v[205];

int n, m;
int vis[205];
int x;

void dfs(int u)
{
for (int i = 0; i < v[u].size(); i++){
if (vis[v[u][i]] == 0){
vis[v[u][i]] = (vis[u] == 1 ? 2 : 1);
dfs(v[u][i]);
}
else if (vis[v[u][i]] == vis[u]){
x = 0;
return;
}
}
return;
}

int main()
{
int a, b;
while (scanf("%d", &n) != EOF){
scanf("%d", &m);
x = 1;
memset(vis, 0, sizeof(vis));
for (int i = 0; i < m; i++){
scanf("%d%d", &a, &b);
v[a].push_back(b);
v[b].push_back(a);
}
vis[0] = 1;
dfs(0);
if (x)
printf("BICOLORABLE.\n");
else
printf("NOT BICOLORABLE.\n");

for (int i = 0; i <= n; i++)
v[i].clear();
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: