Codeforces 841D Leha and another game about graph - 差分
Leha plays a computer game, where is on each level is given a connected graph with n vertices and m edges. Graph can contain multiple edges, but can not contain self loops. Each vertex has an integer di, which can be equal to 0, 1 or - 1. To pass the level, he needs to find a «good» subset of edges of the graph or say, that it doesn't exist. Subset is called «good», if by by leaving only edges from this subset in the original graph, we obtain the following: for every vertex i, di = - 1 or it's degree modulo 2 is equal to di. Leha wants to pass the game as soon as possible and ask you to help him. In case of multiple correct answers, print any of them.
The first line contains two integers n, m (1 ≤ n ≤ 3·105, n - 1 ≤ m ≤ 3·105) — number of vertices and edges.
The second line contains n integers d1, d2, ..., dn ( - 1 ≤ di ≤ 1) — numbers on the vertices.
Each of the next m lines contains two integers u and v (1 ≤ u, v ≤ n) — edges. It's guaranteed, that graph in the input is connected.
Print - 1 in a single line, if solution doesn't exist. Otherwise in the first line k — number of edges in a subset. In the next k lines indexes of edges. Edges are numerated in order as they are given in the input, starting from 1.
1 0
1
-1
4 5
0 0 0 -1
1 2
2 3
3 4
1 4
2 4
0
2 1
1 1
1 2
1
1
3 3
0 -1 1
1 2
2 3
1 3
1
2
In the first sample we have single vertex without edges. It's degree is 0 and we can not get 1.
题目大意 给定一个不包含自环的连通图,从中选出一些边使得特定的点满足入度的奇偶性。
这里主要的问题是要处理要求入度为奇数的点(入度为偶数的点可以不连任何边)。然后仔细研究会发现,一条路径除了两端的点增加的度数为奇数,中间经过的点增加的度数都为偶数,这就很有用了。
现在就考虑用一堆起点和终点(其实只用将要求度数为奇数的点任选两个配对,再选剩下中的两个,以此内推)都是要求入度为奇数的路径把它们的边集异或(因为当两条路径有一条公共的边后就会出事情,所以需要把这条边删掉)后得到的新的边集一定是合法的吗?(当然所有选择的点包含了所有要求入度为奇数的点)
当要求度数为1的点的个数为奇数的时候就不一定了。因为总会存在一个点不满足要求。那么这时候就是没有限制的点的表演时间,就找一条路径把1个没有限制的点和这个点连接起来,路上的边的选择情况异或一下。
至于如何快速搞定这个一堆边集取反的过程呢?
首先考虑如果最终得到的图形上出现圈是否有意义?
答案是没有意义,这一圈的边全都可以去掉,因为圈 = 首位相连的路径,这将意味着圈上任意点的度数加了2,这对奇偶性没有影响,是多余的,可以去掉。
所以我们选择每条路径的起点和终点的时候都要求它们不同,所以最终得到的图形是森林。既然是在树上,就可以干很多事情了,比如树上差分。
然后把对 边的取反信息 下放到子节点上(dfs树上),接着从任意一点进行一次dfs就好了。
Code
/**
* Codeforces
* Problem#431D
* Accepted
* Time: 405ms
* Memory: 41000k
*/
#include <bits/stdc++.h>
using namespace std;
typedef bool boolean; int n, m;
int *gs;
int *rev;
vector<int> *g;
vector<int> *ig;
vector<int> c1, c2; inline void init() {
scanf("%d%d", &n, &m);
g = new vector<int>[n + ];
ig = new vector<int>[n + ];
gs = new int[(n + )];
rev = new int[(n + )];
memset(rev, , sizeof(int) * (n + ));
for(int i = ; i <= n; i++) {
scanf("%d", gs + i);
if(gs[i] == )
c1.push_back(i);
else if(gs[i] == -)
c2.push_back(i);
}
for(int i = , u, v; i <= m; i++) {
scanf("%d%d", &u, &v);
g[u].push_back(v);
g[v].push_back(u);
ig[u].push_back(i);
ig[v].push_back(i);
}
} vector<int> res;
boolean *vis;
void dfs(int node) {
vis[node] = true;
for(int i = ; i < (signed)g[node].size(); i++) {
int& e = g[node][i];
if(vis[e]) continue;
dfs(e);
if(rev[e]) res.push_back(ig[node][i]);
rev[node] ^= rev[e];
}
} inline void solve() {
int sc1 = (signed)c1.size(), sc2 = (signed)c2.size();
if((sc1 & ) && !sc2) {
puts("-1");
return;
}
vis = new boolean[(n + )];
memset(vis, false, sizeof(boolean) * (n + ));
for(int i = ; i < sc1; i += )
rev[c1[i]] = rev[c1[i - ]] = ;
if(sc1 & )
rev[c1[sc1 - ]] = rev[c2[]] = ;
dfs();
sc1 = (signed)res.size();
printf("%d\n", sc1);
for(int i = ; i < sc1; i++)
printf("%d\n", res[i]);
} int main() {
init();
solve();
return ;
}
Codeforces 841D Leha and another game about graph - 差分的更多相关文章
- CodeForces - 841D Leha and another game about graph
给出一个连通图,并给每个点赋一个d值0或1或-1,要求选出一个边的集合,使得所有的点i要么d[i] == -1,要么 dgree[i] % 2 == d[i],dgree[i]代表i结点的度数. 考虑 ...
- CodeForces 840B - Leha and another game about graph | Codeforces Round #429(Div 1)
思路来自这里,重点大概是想到建树和无解情况,然后就变成树形DP了- - /* CodeForces 840B - Leha and another game about graph [ 增量构造,树上 ...
- 【CodeForces】841D. Leha and another game about graph(Codeforces Round #429 (Div. 2))
[题意]给定n个点和m条无向边(有重边无自环),每个点有权值di=-1,0,1,要求仅保留一些边使得所有点i满足:di=-1或degree%2=di,输出任意方案. [算法]数学+搜索 [题解] 最关 ...
- Codeforces Round #429 (Div. 2/Div. 1) [ A/_. Generous Kefa ] [ B/_. Godsend ] [ C/A. Leha and Function ] [ D/B. Leha and another game about graph ] [ E/C. On the Bench ] [ _/D. Destiny ]
PROBLEM A/_ - Generous Kefa 题 OvO http://codeforces.com/contest/841/problem/A cf 841a 解 只要不存在某个字母,它的 ...
- Codeforces Round #429 (Div. 2) - D Leha and another game about graph
Leha and another game about graph 题目大意:给你一个图,每个节点都有一个v( -1 , 0 ,1)值,要求你选一些边,使v值为1 的点度数为奇数,v值为0的度数为偶数 ...
- Codeforces 841 D - Leha and another game about graph
D - Leha and another game about graph 思路:首先,如果所有点的度数加起来是奇数,且没有-1,那么是不可以的. 其他情况都可以构造,我们先dfs出一个生成树,然后从 ...
- Codeforces Round #485 (Div. 2) F. AND Graph
Codeforces Round #485 (Div. 2) F. AND Graph 题目连接: http://codeforces.com/contest/987/problem/F Descri ...
- Codeforces 1109D. Sasha and Interesting Fact from Graph Theory
Codeforces 1109D. Sasha and Interesting Fact from Graph Theory 解题思路: 这题我根本不会做,是周指导带飞我. 首先对于当前已经有 \(m ...
- CodeForces 840A - Leha and Function | Codeforces Round #429 (Div. 1)
/* CodeForces 840A - Leha and Function [ 贪心 ] | Codeforces Round #429 (Div. 1) A越大,B越小,越好 */ #includ ...
随机推荐
- HTTP通信机制
HTTP通信机制是在一次完整的HTTP通信过程中,Web浏览器与Web服务器之间将完成下列7个步骤: 1. 建立TCP连接 在HTTP工作开始之前,Web浏览器首先要通过网络与Web服务器建立连接, ...
- AIX挂载NFS写入效率低效解决
背景: Linux是NFS的Server端,AIX是NFS的Client端(此外,有一个Linux也作为Client端对比测试). 1.NFS对应的底层设备是闪存卡,本地测试I/O写性能可达2GB/s ...
- MySQL报错
1,使用mysqldump导出数据报错: mysqldump: Error 2020: Got packet bigger than 'max_allowed_packet' bytes when d ...
- C#7.0新特性(VS2017可用)
分享一下其实2016年12月就已经公布了的C#7.0的新特性吧,虽然很早就出来了,但咱这IDE不支持啊.. 不过在昨天的VS2017中已经完美可以支持使用了. E文好的,移步官方介绍地址:https: ...
- mybatis3 date 的处理
<if test="startTime!=null and startTime!=''"> <![CDATA[ and DATE_FORMAT(create_ti ...
- MyEclipse10中文乱码
1 进入window->preferences general->content types,可以设置Text对应的default encoding值为UTF-8或为空,然后点击updat ...
- Linux 压缩解压缩命令详解
tar -c: 建立压缩档案-x:解压-t:查看内容-r:向压缩归档文件末尾追加文件-u:更新原压缩包中的文件 这五个是独立的命令,压缩解压都要用到其中一个,可以和别的命令连用但只能用其中一个.下面的 ...
- Yii2将查询数据变为键值对数组及查询构建器
- 转自大神的KM想法
我第一次理解KM算法看到大神的讲解不胜感激这km挺神奇的接下来就见识一下这个大牛的吧 转自 http://blog.csdn.net/wuxinxiaohuangdou/article/details ...
- Spring tokenizeToStringArray
tokenizeToStringArray: StringUtils.tokenizeToStringArray(pattern, this.pathSeparator, this.trimToken ...