Luogu2715 小Z的游戏分队
小Z受不了寂寞,准备举办一次DOTA比赛,为了能让ACM班全部都参加比赛,他还特制了一张DOTA地图能够支持任意多人打任意多人。
现在问题来了,怎么把这么多人分成两队?小Z的想法是,每个人报上自己愿意同队的同学,接着小Z会按如下要求将所有人分为两队:
对任意同学甲,和同学甲同队的人,必须都是同学甲愿意同队的同学。
小Z希望两队的人数差尽量小,如果这种分组不存在,那么输出No solution。
输入输出格式
输入格式:
第1行为N,表示一共有多少个学生。
之后2~N+1行,每行表示这个学生信任的同学的名单,以0结束。
输出格式:
1行,如果解存在,输出两队的人数,将人数比较小的那队放在前面;如果解不存在,输出No solution。
输入输出样例
输入样例#1:
5 3 4 5 0 1 3 5 0 2 1 4 5 0 2 3 5 0 1 2 3 4 0输出样例#1:
No solution输入样例#2:
5 2 3 5 0 1 4 5 3 0 1 2 5 0 1 2 3 0 4 3 2 1 0输出样例#2:
2 3说明
【数据规模】
对于 30% 的数据,N<=10;
对于 100% 的数据,N<=2000。
poj1112的超级弱化版。。。
构造反图(既如果两个人不能在一个组就连一条边),如果构造出的图不是二分图则无解,因为此时会存在某个人在两个组的时候都会有不能在一个组的人。
然后对于每一个编号(dfs的时候对于在同一条内部链的人的编号)的人可以看作一左一右两个value,每次的选择就相当于把左右的value互换,然后这就是一个背包dp了。
注意是No solution而不是No Solution
// 动态规划 判定性dp 背包dp 二分图染色 %:pragma GCC optimize(2) #include <iostream> #include <algorithm> #include <cstdio> #include <cstring> #include <cstdlib> #include <vector> using namespace std; const int N = 2010; int n, color[N], like[N][N], val[N][3], cnt; bool f[N][N * 8]; vector<int> G[N]; void dfs(int u, int c, int dfn) { color[u] = c; ++ val[dfn][c]; for(int i = 0 ; i < G[u].size() ; ++ i) { int v = G[u][i]; if(!color[v]) { dfs(v, 3 - c, dfn); } else if(color[u] == color[v]) { puts("No solution"); exit(0); } } } int main() { scanf("%d", &n); for(int i = 1, x ; i <= n ; ++ i) { while(scanf("%d", &x), x) { like[i][x] = 1; } } for(int i = 1 ; i <= n ; ++ i) { for(int j = 1 ; j < i ; ++ j) { if(!(like[i][j] && like[j][i])) { G[i].push_back(j); G[j].push_back(i); } } } for(int i = 1 ; i <= n ; ++ i) { if(!color[i]) { dfs(i, 1, ++ cnt); } } memset(f, 0, sizeof(f)); #define dp(i, j) f[i][j + 4000] dp(0, 0) = 1; for(int i = 1 ; i <= cnt ; ++ i) { for(int j = -2000 ; j <= 2000 ; ++ j) { dp(i, j) |= dp(i - 1, j - val[i][1] + val[i][2]) | dp(i - 1, j - val[i][2] + val[i][1]); } } for(int i = 0 ; i <= 2000 ; ++ i) { if(dp(cnt, i)) { int x = (n + i) / 2, y = n - x; if(x > y) swap(x, y); printf("%d %d\n", x, y); return 0; } else if(dp(cnt, -i)) { int x = (n - i) / 2, y = n - x; if(x > y) swap(x, y); printf("%d %d\n", x, y); return 0; } } puts("No solution"); }