CF-1354 E. Graph Coloring(二分图,背包,背包方案输出)
E. Graph Coloring
n个点m条边的无向图,不保证联通,给每个点标号1,2,3。1号点个数n1,2号点个数n2,3号点个数n3。且每条边的两点,标号之差绝对值为1。如果有合法方案,需输出方案。
考虑每个联通子图,2只可以和1或者3连边,1只能和2连边,3只能和2连边,那么将1,3归为一堆,2归为一堆。每一堆内不存在边,构成一个独立点集,那么很明显是一个二分图,每次DFS可以找到二分图两部点的个数,如果存在奇环那么直接输出NO
对于每个联通子图,一个二分图,假设左部有 x 个点,右部有y个点,那么可以给x个点标2号,或者给 y 个点标2号。问最后能否刚好凑够 n2 个2号点。这显然是一个背包问题。
每个联通子图是一个物品,二分图两部分点的数量就是体积,可以记录路径也可以不记录。因为目标是凑够 n2 个点,那么如果第 i 个物品选择的不是二分图中标记为 2 的点,那么认为这个物品是反选的,也是将标记为 1 的点最终标记成了 2。
对于1号点和3号点,在整个过程中都被标记成了1,所以只需要输出所有标记为1的点即可,如果n1个 1 全部输出,那么再紧接着输出 3即可。
需要标记的东西:第 i 个物品的两个体积(左部点个数和右部点个数), 每个点的标号,每个点所属的物品编号,物品是否要反选(最后DP结束后倒推即可)
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int inf = 0x3f3f3f3f;
#define dbg(x...) do { cout << "\033[32;1m" << #x <<" -> "; err(x); } while (0)
void err() { cout << "\033[39;0m" << endl; }
template<class T, class... Ts> void err(const T& arg,const Ts&... args) { cout << arg << " "; err(args...); }
const int N = 5000 + 5;
const int M = 200010;
int head[N], ver[M], nxt[M], tot, cnt;
int n, m, n1, n2, n3;
int c[N], be[N], c1[N], c2[N], rev[N];
int d[N][N];
void add(int x, int y){
ver[++tot] = y, nxt[tot] = head[x], head[x] = tot;
}
bool dfs(int x, int col){
c[x] = col;
be[x] = cnt;
if(c[x] == 1) c1[cnt] ++;
else c2[cnt] ++;
for(int i=head[x];i;i=nxt[i]){
int y = ver[i];
if(!c[y]){
if(!dfs(y, 3 - col)) return false;
}
if(c[y] + c[x] != 3) return false;
}
return true;
}
int main(){
scanf("%d%d", &n,&m);
scanf("%d%d%d", &n1, &n2, &n3);
for(int i=1;i<=m;i++){
int x, y;scanf("%d%d", &x, &y);
add(x, y);add(y, x);
}
d[0][0] = 1;
for(int i=1;i<=n;i++){
if(c[i]) continue;
cnt++;
if(!dfs(i, 1)){
puts("NO");
return 0;
}
for(int j=c1[cnt];j<=n2;j++){
d[cnt][j] |= d[cnt-1][j-c1[cnt]];
}
for(int j=c2[cnt];j<=n2;j++){
d[cnt][j] |= d[cnt-1][j-c2[cnt]];
}
}
if(!d[cnt][n2]) {
puts("NO");return 0;
}
puts("YES");
while(cnt){
rev[cnt] = d[cnt-1][n2-c1[cnt]];
if(rev[cnt]) n2 -= c1[cnt];
else n2 -= c2[cnt];
cnt --;
}
for(int i=1;i<=n;i++){
if(rev[be[i]]) c[i] = 3 - c[i];
if(c[i] == 2) putchar('2');
else if(n1 > 0) putchar('1'), n1--;
else putchar('3');
}
return 0;
}
CF-1354 E. Graph Coloring(二分图,背包,背包方案输出)的更多相关文章
- Codeforces 664D Graph Coloring 二分图染色
题意: 一个无向图的每条边为红色或蓝色,有这样一种操作:每次选一个点,使与其相邻的所有边的颜色翻转. 求解是否可以经过一系列操作使所有的边颜色相同,并输出最少操作次数和相应的点. 分析: 每个点要么选 ...
- luogu P2066 机器分配[背包dp+方案输出]
题目背景 无 题目描述 总公司拥有高效设备M台,准备分给下属的N个分公司.各分公司若获得这些设备,可以为国家提供一定的盈利.问:如何分配这M台设备才能使国家得到的盈利最大?求出最大盈利值.其中M≤15 ...
- [多校联考2019(Round 5 T2)]蓝精灵的请求(二分图染色+背包)
[多校联考2019(Round 5)]蓝精灵的请求(二分图染色+背包) 题面 在山的那边海的那边住着 n 个蓝精灵,这 n 个蓝精灵之间有 m 对好友关系,现在蓝精灵们想要玩一个团队竞技游戏,需要分为 ...
- poj 1419 Graph Coloring
http://poj.org/problem?id=1419 题意: 一张图黑白染色,相邻点不能都染黑色,最多能染几个黑色点 最大点独立集 但是图不能同构为二分图,不能用二分图匹配来做 那就爆搜吧 还 ...
- 【POJ】1419:Graph Coloring【普通图最大点独立集】【最大团】
Graph Coloring Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 5775 Accepted: 2678 ...
- POJ 1419 Graph Coloring(最大独立集/补图的最大团)
Graph Coloring Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 4893 Accepted: 2271 ...
- POJ1419 Graph Coloring(最大独立集)(最大团)
Graph Coloring Time Limit: 1000MS Memor ...
- uva193 - Graph Coloring
Graph Coloring You are to write a program that tries to find an optimal coloring for a given graph. ...
- UVA Graph Coloring
主题如以下: Graph Coloring You are to write a program that tries to find an optimal coloring for agiven ...
随机推荐
- 【Java基础】面向对象下
面向对象下 这一章主要涉及其他关键字,包括 this.super.static.final.abstract.interface.package.import 等. static 在 Java 类中, ...
- 【C++】《C++ Primer 》第九章
第九章 顺序容器 一.顺序容器概述 顺序容器(sequential container):为程序员提供了控制元素存储和访问顺序的能力.这种顺序不依赖于元素的值,而是与元素加入容器时的位置相对应. 不同 ...
- PMP知识领域
· 十大知识领域 整合-项目整合管理 识别.定义.组合.统一和协调个项目管理过程组的各种过程和活动而展开的活动与过程. 整合:统一.合并.沟通和简历联系:贯穿项目始终 七个过程组 一.制定项目章程(启 ...
- MySQL sql命令行操作数据库
数据库命令行操作 命令行操作数据库, [if exists] 可加可不加, 命令行操作一定要加英文分号 ; 结尾 创建数据库 : create database [if not exists] 数据库 ...
- 【Oracle】删除(释放)数据文件/表空间流程
oracle删除(释放)数据文件/表空间流程 生产环境:数据库里空间不足,niptest 表空间251G,只使用了17G 再alter database datafile '...../niptest ...
- linux查看文件夹和磁盘内存及服务器对应的ip
多进程统计cpu 数目 n_cpu = multiprocessing.cpu_count() print(n_cpu) 查看文件夹占用磁盘空间 du -h --max-depth=1 /path 查 ...
- 【开源】我和 JAP(JA Plus) 的故事
JA Plus 故事 程序员的故事如此简单之绕不过去的开源情结 我们准备做一件伟大的事,也可以说是一件真真正正普惠的事. 絮 是的,你没有看错,就是"絮"而非"序&quo ...
- 使用gui_upload的总结
今天使用gui_upload函数将文本文件的内容读取到内表.出现了一个问题,总是程序宕掉,出项的提示是 Type conflict when calling a function module. 原来 ...
- 对于Update Function Modules的一点说明
To be able to call a function module in an update work process, you must flag it in the Function Bui ...
- JavaSE 基础知识(常识概念 + 基础语法)问答总结/面试题 —— 讲给应届生的 Java 开源知识项目
写在最前面 这个项目是从20年末就立好的 flag,经过几年的学习,回过头再去看很多知识点又有新的理解.所以趁着找实习的准备,结合以前的学习储备,创建一个主要针对应届生和初学者的 Java 开源知识项 ...