sgu172:eXam(二分图染色)

来源:互联网 发布:12月份php好找工作吗 编辑:程序博客网 时间:2024/05/04 08:04
题意:
对于每一个学生要报两门专业,而每个人所报的专业又不能在同一天授课,求出是否可以按一定的分配方法使得在两天
之内即可上完全部课程。一共有N(1<=N<=200)门课程,有M(1<=M<=30000)个学生。
分析:
我们对于不能在同一天授课的两门之间连一条边。
由于M>=1,所以图至少是二分图。
如果图是二分图,我们可以把左边的安排在第一天上,右边安排在第二天上,满足题意;
如果不是,那我们就找不到一种满足题意得方案。
总之就是判定图是否是二分图即可。
那么如何判断呢?
我们可以用染色法,按dfs遍历,对于经过的点010101....的染色,如果出现两相邻的点颜色一样,就证明该图非二分图。
over...
#include <cstdio>#include <iostream>#include <cstring>using namespace std;const int MAXN = 205;int n, m;bool g[MAXN][MAXN];int col[MAXN];bool flag = 1;int match[MAXN];bool used[MAXN], gone[MAXN][MAXN];void dfs(int cur, int c){col[cur] = c;for(int i = 1; i <= n; ++i)if(g[cur][i] && flag && !gone[cur][i]){gone[cur][i] = gone[i][cur] = 1;if(col[i] == -1)dfs(i, c^1);else if(col[i] == col[cur]){flag = 0;return ;}}}int main(){cin >> n >> m;for(int i = 1; i <= m; ++i){int x, y;cin >> x >> y;g[x][y] = g[y][x] = 1;}memset(col, 0xfffff, sizeof(col));for(int i = 1; i <= n; ++i)if(col[i] == -1)dfs(i, 0);if(!flag){cout << "no" << endl;return 0;}else {cout << "yes" << endl;int ans = 0;for(int i = 1; i <= n; ++i)if(!col[i])ans++;cout << ans << endl;for(int i = 1; i <= n; ++i)if(!col[i]) cout << i << ' ';}return 0;}

0 0
原创粉丝点击