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 ...
随机推荐
- AtCoder Beginner Contest 188 F - +1-1x2 思维题
题目描述 给你两个数 \(x\),\(y\) 可以对 \(x\) 进行 \(+1,-1\) 或 \(\times 2\) 的操作 问最少操作多少次后变为 \(y\) \(x,y \leq 10^{18 ...
- 算法设计与分析 - 主定理Master theorem (分治法递推时间复杂度)
英文原版不上了 直接中文 定义 假设有递推关系式T(n)=aT(n/b)+f(n) 其中n为问题规模 a为递推的子问题数量 n/b为每个子问题的规模(假设每个子问题的规模基本一样) f(n)为递推以外 ...
- Zabbix 4.0.24 完整安装
依赖包安装: yum install net-snmp* libssh-devel libssh2-devel -y Zabbix server安装: wget https://cdn.zabbix. ...
- 【Git】2、Linux快速安装Git环境 & oh-my-zsh
Linux快速安装Git环境 文章目录 Linux快速安装Git环境 1.Linux安装Git 2.安装zsh 3.安装oh-my-zsh 3.1.安装oh-my-zsh 3.2. 测试验证 4.小结 ...
- 【Oracle LISTNER】oracle Listener 宕机解决办法
今天想起了很久没用的oracle库,用plsql尝试连接,发现报超时错误,以为是偶然,多次尝试连接,发现还是超时,于是登录到系统中,查看数据库情况,发现正常查询和修改添加,感觉不是数据库问题,查看监听 ...
- 树莓派3B装ubuntu server后开启wifi
树莓派官网选择ubuntu server下载映像 step 1: 使用SDFormatter格式化SD卡: step2: 使用win32diskimager工具将映像写入准备好的SD卡: step3: ...
- kafka(一)入门
一.消息引擎系统 这类系统引以为豪的消息传递属性,像引擎一样,具备某种能量转换传输的能力 消息引擎系统是一组规范,企业利用这组规范在不同系统之间传递语义准确的消息,实现松耦合的异步式数据传递.通俗地讲 ...
- Java优先队列PriorityQueue的各种打开方式以及一些你不知道的细节
目录 Java优先队列PriorityQueue的各种打开方式以及一些你不知道的细节 优先队列的默认用法-从小到大排序 对String类用优先队列从大到小排序 通过自定义比较器对自定义的类进行从小到大 ...
- Ubuntu18.04完全卸载mysql5.7并安装mysql8.0的安装方法
Ubuntu18.04版本下,如果直接输入: sudo apt install mysql-server 命令,会默认安装mysql5.7版本,安装过程并没有提示输入密码,安装完成后也无法正常登录,这 ...
- pandas模块的使用详解
为什么学习pandas numpy已经可以帮助我们进行数据的处理了,那么学习pandas的目的是什么呢? numpy能够帮助我们处理的是数值型的数据,当然在数据分析中除了数值型的数据还有好多其他类型的 ...