大型补档计划

题目链接

看到分成两组,想到二分图判定 + 染色。

二分图的特点是两个有矛盾的点连一条边,考虑在这道题中,如果 \(a, b\) 中有一个人不认识对方(或者两个人互不认识),就不可能分在一组,可以在 \((a, b)\) 连一条无向边。

但是由于图不连通,每个联通块染色跑出两种颜色的数量 \(c_1, c_2\) 后(跑不出来无解),让两队数量接近,等价于让一队的数量 $ <= \frac{N}{2}$ 且最大,我们可以把这两个当做一组,把 \(cnt\) 个联通块当做物品,做分组背包选出一队的人员(并且强制选择),因为答案输出任意一组方案,倒序递推出答案即可。

切忌强制转移!因为不强制转移可能出现一组都不选,而题目要求每个队员必须在一队(会 WA 53)

#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
using namespace std;
const int N = 105;
int n, c1, c2, cnt, col[N], vis[N];
int f[N][N], a[N][N], b[N][N], d[N];
vector<int> ans[2];
bool g[N][N];
bool dfs(int u, int t, int c) {
col[u] = c, vis[u] = t;
c == 1 ? c1++ : c2++;
for (int v = 1; v <= n; v++) {
if (v != u && (!g[u][v] || !g[v][u])) {
if (!col[v]) {
if (!dfs(v, t, 3 - c)) return false;
} else if(col[v] == c) return false;
}
}
return true;
}
void work(int i, int j) {
if (i == 0) return;
if (b[i][j]) d[i] = b[i][j];
work(i - 1, a[i][j]);
}
int main() {
memset(f, 0xcf, sizeof f);
f[0][0] = 0;
scanf("%d", &n);
for (int i = 1, x; i <= n; i++) {
while (scanf("%d", &x), x) {
g[i][x] = true;
}
}
int V = n >> 1;
for (int i = 1; i <= n; i++) {
if (!vis[i]) {
c1 = 0, c2 = 0;
if(!dfs(i, ++cnt, 1)) {
puts("No solution");
return 0;
}
for (int j = V; j >= 0; j--) {
if (j >= c1 && f[cnt - 1][j - c1] + c1 >= f[cnt][j]) {
f[cnt][j] = f[cnt - 1][j - c1] + c1;
a[cnt][j] = j - c1, b[cnt][j] = 1;
}
if (j >= c2 && f[cnt - 1][j - c2] + c2 >= f[cnt][j]) {
f[cnt][j] = f[cnt - 1][j - c2] + c2;
a[cnt][j] = j - c2, b[cnt][j] = 2;
}
}
}
}
int res = 0, t = -1;
for (int i = 0; i <= V; i++)
if (f[cnt][i] > res) res = f[cnt][i], t = i;
work(cnt, t);
for (int i = 1; i <= n; i++) {
if ((col[i] == 1 && d[vis[i]] == 1) || (col[i] == 2 && d[vis[i]] == 2)) ans[0].push_back(i);
else ans[1].push_back(i);
}
for (int i = 0; i < 2; i++) {
printf("%d ", ans[i].size());
for (int j = 0; j < ans[i].size(); j++) printf("%d ", ans[i][j]);
puts("");
}
return 0;
}

Acwing 405. 将他们分好队的更多相关文章

  1. P4113 [HEOI2012]采花 (莫队TLE)

    思路 update 11.2 树状数组AC 本题莫队过不去,会TLE ----------------------- 但也是个不错的莫队练手题 ------------------------ 毕竟C ...

  2. 关于MySQL相关的查看显示信息:

    关于MySQL相关的查看显示信息: 数据库范围: 一.查看所有的数据库:(仅仅是看数据库数量与名字) mysql> show databases; 二.查看某个数据库的创建信息:(主要看数据库的 ...

  3. 排球积分规则功能说明书(spec)

    排球规则: 由技术性规定.非技术性规定和场地设备要求等方面的内容组成的.每场比赛仍为五局三胜,前四局每局先得25分为胜,第五局先得15分者为胜.当出现24平或14平时,要继续比赛至领先2分才能取胜. ...

  4. bzoj1006 [HNOI2008]神奇的国度

    1006: [HNOI2008]神奇的国度 Time Limit: 20 Sec  Memory Limit: 162 MBSubmit: 2304  Solved: 1043 Description ...

  5. BZOJ 1006 [HNOI2008] 神奇的国度(简单弦图的染色)

    题目大意 K 国是一个热衷三角形的国度,连人的交往也只喜欢三角原则.他们认为三角关系:即 AB 相互认识,BC 相互认识,CA 相互认识,是简洁高效的.为了巩固三角关系,K 国禁止四边关系,五边关系等 ...

  6. 【BZOJ1006】【HNOI2008】神奇的国度(弦图染色)

    1006: [HNOI2008]神奇的国度 Time Limit: 20 Sec  Memory Limit: 162 MBSubmit: 1467  Solved: 603[Submit][Stat ...

  7. 越狱Season 1-Episode 17: J-Cat

    Season 1, Episode 17: J-Cat -Pope: Hey, that's looking good. 嗨,看起来真棒 You're making some real progres ...

  8. bzoj1006 神奇的国度

    Description K国是一个热衷三角形的国度,连人的交往也只喜欢三角原则.他们认为三角关系:即AB相互认识,BC相互认识,CA相互认识,是简洁高效的.为了巩固三角关系,K国禁止四边关系,五边关系 ...

  9. jQuery实现模拟滚动条效果;

    滚动条在web开发中,很常见,原生的HTML滚动条很难看,因此很多网站借助JS来模拟实现滚动条效果: 滚动条的实现原理其实比较简单,拿垂直滚动条来说: 1),最外层容器需要设置overflow:hid ...

随机推荐

  1. C++如何实现多态

    1.   什么是多态多态是C++中的一个重要的基础,面向对象编程语言中,接口的多种不同的实现方式即为多态.2.   多态带来的好处多态带来两个明显的好处:一是不用记大量的函数名了,二是它会依据调用时的 ...

  2. select限制之文件描述符限制

    1.一个进能够打开的最大文件描述符限制.可以通过两种方式修改ulimit -n :获取最大文件描述符个数ulimit -n 2048:修改为2048个 该限制的测试代码: 客户端程序: /* 1.se ...

  3. 解决Ubuntu配置nginx出现的问题

    Ubuntu18.04配置nginx出现的各种错误 缺少pcre库 编译nginx 出现错误 安装pcre库,出现错误 手动编译安装pcre库 (1)下载并解压pcre库 wget https://f ...

  4. [原题复现]强网杯 2019 WEB高明的黑客

    简介  原题复现:  考察知识点:python代码编写能力...  线上平台:https://buuoj.cn(北京联合大学公开的CTF平台) 榆林学院内可使用信安协会内部的CTF训练平台找到此题 简 ...

  5. [原题复现]2019强网杯WEB-随便注(多种方法)

    简介 原题复现:https://gitee.com/xiaohua1998/qwb_2019_supersqli  考察知识点:SQL注入漏洞-堆叠注入  线上平台:https://buuoj.cn( ...

  6. FL Studio时间面板讲解

    今天我们一起来学习一下FL Studio时间面板的知识.看到这个名词我们一定就会想到该功能跟时间是脱不了关系的,是的,它就是用来显示时间的.它显示当前时间的方法不是很单一,而是有好几个,具体有哪几个下 ...

  7. 使用axios实现登录功能

    1.创建一个login.vue页面 1.1写页面components/Login.vue 在 src/components 下创建 Login.vue 页面 <template> < ...

  8. [LGOJ1273]有线电视网

    solution 用了一个很有意思的转移方法. $dp[i][j] $ 表达 \(i\) 作为根,\(j\)个终端时最大的收益,即钱数,当\(0\leq dp[1][i]\)时,即以1为根可以转移到\ ...

  9. The Balance POJ - 2142

    首先,可以知道题目要求解一个\(ax+by=c\)的方程,且\(x+y\)最小. 感性证明: 当\(a>b\)时,\(y\)取最小正整数解,\(b\)减的多,\(a\)增的少,此时\(x+y\) ...

  10. 语法解析器续:case..when..语法解析计算

    之前写过一篇博客,是关于如何解析类似sql之类的解析器实现参考:https://www.cnblogs.com/yougewe/p/13774289.html 之前的解析器,更多的是是做语言的翻译转换 ...