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.

Input

The first line contains two integers nm (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.

Output

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.

Examples

input

1 01

output

-1

input

4 50 0 0 -11 22 33 41 42 4

output

0

input

2 11 11 2

output

11

input

3 30 -1 11 22 31 3

output

12

Note

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

 1 /**
 2  * Codeforces
 3  * Problem#431D
 4  * Accepted
 5  * Time: 405ms
 6  * Memory: 41000k
 7  */
 8 #include <bits/stdc++.h>
 9 using namespace std;
10 typedef bool boolean;
11
12 int n, m;
13 int *gs;
14 int *rev;
15 vector<int> *g;
16 vector<int> *ig;
17 vector<int> c1, c2;
18
19 inline void init() {
20     scanf("%d%d", &n, &m);
21     g = new vector<int>[n + 1];
22     ig = new vector<int>[n + 1];
23     gs = new int[(n + 1)];
24     rev = new int[(n + 1)];
25     memset(rev, 0, sizeof(int) * (n + 1));
26     for(int i = 1; i <= n; i++) {
27         scanf("%d", gs + i);
28         if(gs[i] == 1)
29             c1.push_back(i);
30         else if(gs[i] == -1)
31             c2.push_back(i);
32     }
33     for(int i = 1, u, v; i <= m; i++) {
34         scanf("%d%d", &u, &v);
35         g[u].push_back(v);
36         g[v].push_back(u);
37         ig[u].push_back(i);
38         ig[v].push_back(i);
39     }
40 }
41
42 vector<int> res;
43 boolean *vis;
44 void dfs(int node) {
45     vis[node] = true;
46     for(int i = 0; i < (signed)g[node].size(); i++) {
47         int& e = g[node][i];
48         if(vis[e])    continue;
49         dfs(e);
50         if(rev[e])    res.push_back(ig[node][i]);
51         rev[node] ^= rev[e];
52     }
53 }
54
55 inline void solve() {
56     int sc1 = (signed)c1.size(), sc2 = (signed)c2.size();
57     if((sc1 & 1) && !sc2) {
58         puts("-1");
59         return;
60     }
61     vis = new boolean[(n + 1)];
62     memset(vis, false, sizeof(boolean) * (n + 1));
63     for(int i = 1; i < sc1; i += 2)
64         rev[c1[i]] = rev[c1[i - 1]] = 1;
65     if(sc1 & 1)
66         rev[c1[sc1 - 1]] = rev[c2[0]] = 1;
67     dfs(1);
68     sc1 = (signed)res.size();
69     printf("%d\n", sc1);
70     for(int i = 0; i < sc1; i++)
71         printf("%d\n", res[i]);
72 }
73
74 int main() {
75     init();
76     solve();
77     return 0;
78 }
时间: 2024-09-30 10:35:02

Codeforces 841D Leha and another game about graph - 差分的相关文章

CodeForces 840B - Leha and another game about graph | Codeforces Round #429(Div 1)

思路来自这里,重点大概是想到建树和无解情况,然后就变成树形DP了- - /* CodeForces 840B - Leha and another game about graph [ 增量构造,树上差分 ] | Codeforces Round #429(Div 1) 题意: 选择一个边集合,满足某些点度数的奇偶性 分析: 将d = 1的点连成一颗树,不在树上的点都不连边. 可以发现,当某个节点u的所有子节点si均可操控 (u, si) 来满足自身要求 即整棵树上至多只有1个点不满足自身要求,

Codeforces 841 D - Leha and another game about graph

D - Leha and another game about graph 思路:首先,如果所有点的度数加起来是奇数,且没有-1,那么是不可以的. 其他情况都可以构造,我们先dfs出一个生成树,然后从叶子节点开始往上处理 对于节点u和v,边u -> v,如果d[v]等于1,那么就要选这条边,d[u]取反(改变状态) 这样的话v就可以不用管了,一直这样下去直到根节点,出了根节点,其他点都能满足 如果存在-1,就把-1放在根节点,如果没有的话,以任意节点为根都可以,因为奇偶性 不变. #pragma

Codeforces Round #261 (Div. 2)——Pashmak and Graph

题目链接 题意: n个点,m个边的有向图,每条边有一个权值,求一条最长的路径,使得路径上边值严格递增.输出路径长度 (2?≤?n?≤?3·105; 1?≤?m?≤?min(n·(n?-?1),?3·105)) 分析: 因为路径上会有重复点,而边不会重复,所以最开始想的是以边为状态进行DP,get TLE--后来想想,在以边为点的新图中,边的个数可能会很多,所以不行. 考虑一下裸的DP如何做:路径上有重复点,可以将状态详细化,dp[i][j]表示i点以j为结束边值的最长路,但是数据不允许这样.想想

CodeForces 840A - Leha and Function | Codeforces Round #429 (Div. 1)

/* CodeForces 840A - Leha and Function [ 贪心 ] | Codeforces Round #429 (Div. 1) A越大,B越小,越好 */ #include <bits/stdc++.h> using namespace std; const int N = 2e5+5; int a[N], b[N], c[N], n; int aa[N], bb[N]; bool cmp1(int x, int y) { return a[x] > a[y

codeforces 794F Leha and security system

目录 codeforces 794F Leha and security system 题意 题解 Code codeforces 794F Leha and security system 题目传送门 题意 给出一个长度为\(n\)的序列,有两种操作: 1.将区间\([l,r]\)中每一个元素的数字\(x\)改为\(y\). 2.询问区间\([l,r]\)的元素之和. 一共\(q\)次操作.\((1 \leq n,q \leq 10^5)\) 题解 看起来就很可做的题目,实际上只是线段树的应用

【推导】【DFS】Codeforces Round #429 (Div. 1) B. Leha and another game about graph

题意:给你一张图,给你每个点的权值,要么是-1,要么是1,要么是0.如果是-1就不用管,否则就要删除图中的某些边,使得该点的度数 mod 2等于该点的权值.让你输出一个留边的方案. 首先如果图内有-1,那么必有解.否则如果初始不合法的点数为偶数,那么必有解,否则无解.因为删一条边,要么使图中不合法的点数+2,要么不变,要么-2. 如果有解,构造图的任意一个生成树,如果有-1,就让-1为根,否则任意结点为根.然后从叶子向根定每个点的入度数,由于自底向上,一个结点的儿子边都被处理完后,只需要决定父边

Codeforces 566 F. Clique in the Divisibility Graph

Codeforces 566F 的传送门 As you must know, the maximum clique problem in an arbitrary graph is NP-hard. Nevertheless, for some graphs of specific kinds it can be solved effectively. Just in case, let us remind you that a clique in a non-directed graph is

Codeforces 724 G Xor-matic Number of the Graph 线性基+DFS

G. Xor-matic Number of the Graph http://codeforces.com/problemset/problem/724/G 题意:给你一张无向图.定义一个无序三元组(u,v,s)表示u到v的(不一定为简单路径)路径上xor值为s.求出这张无向图所有不重复三元组的s之和.1≤n≤10^5,1≤m≤2*10^5. 想法: 如果做过[Wc2011 xor]这道题目(题解),那么问题变得简单起来了. ①假设我们钦定一个(u,v),设任意一条u->v的路径xor值为X,

codeforces 702E Analysis of Pathes in Functional Graph(倍增)

E. Analysis of Pathes in Functional Graph You are given a functional graph. It is a directed graph, in which from each vertex goes exactly one arc. The vertices are numerated from 0 to n - 1. Graph is given as the array f0, f1, ..., fn - 1, where fi