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");
}

浙公网安备 33010602011771号