Codeforces Round #429 (Div. 2)-(DFS)

来源:互联网 发布:autodesk 打印 软件 编辑:程序博客网 时间:2024/05/21 22:39
D. Leha and another game about graph
time limit per test
3 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

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 01 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·105n - 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)其他点的出度%2==点的权值

然后问你留下的点的编号和边的数量。。。。。

题解:开始是懵逼的啊,然后上午看了看,没什么思路,晚上看了室友补了这道题,有了思路,打cf的时候感

觉这题好难啊,当时就听人说是dfs瞎搞搞,然而没搞出来啊,但是当时把无解的情况给搞出来了,出度为偶

数的点连的边不用考虑了,很简单,大不了把边给删完,但是假如说这个点连了一个权值为奇数的点呢?

其实也很好办,别忘了还有一些没有限制的点呢,我们可以强行把其转化成合法状态。。呢假如没有这些特殊

点呢。。。。这就是我们要考虑的无解情况,也就是没有权值为-1的点时,当前的图能否修改成合法图,首先

要考虑的就是权值为奇数的点情况,我们可以发现当权值为奇数的点有偶数个时肯定有解,自己举例子吧。。

偶数是没有限制的,之前已经说过了,所以奇数和偶数相连我们只考虑奇数,综上:无解情况只有没有特殊点

并且权值为奇数的点有奇数个,剩下的问题是怎么修改,既然肯定能改成功,呢么我们随便找点?你可以试

试,你一定会wa7到死的。。。。我们再来想一下之前的无解非法状态怎么转化过来的,是不是要利用这些特

殊点。。。没错就是这个原理,假如有这些特殊点,并且你不用这些特殊点无法转化成目标图的时候就要首先

利用这些特殊点的性质了,好像是性质可以传递?

#include<map>     #include<stack>            #include<queue>            #include<vector>    #include<string>  #include<math.h>            #include<stdio.h>            #include<iostream>            #include<string.h>            #include<stdlib.h>    #include<algorithm>   #include<functional>    using namespace std;typedef long long  ll;#define inf  1000000000       #define mod 1000000007             #define maxn  308050  #define lowbit(x) (x&-x)            #define eps 1e-9  int a[maxn], flag[maxn];bool vis[maxn];struct node{int x, y;}b[maxn];vector<node>q[maxn];int dfs(int x){int i, j, ans;vis[x] = 1;ans = a[x];for (i = 0;i < q[x].size();i++){node v = q[x][i];if (vis[v.x])continue;if (dfs(v.x)){ans ^= 1;flag[v.y] = 1;}}if (a[x] == -1)return 0;return ans;}int main(void){int n, m, i, j, x, y, e1 = 0, e2 = 0, sum = 0;scanf("%d%d", &n, &m);for (i = 1;i <= n;i++){scanf("%d", &a[i]);if (a[i] == -1)e1 = i;if (a[i] == 1)e2++;}for (i = 1;i <= m;i++){scanf("%d%d", &x, &y);node tmp;tmp.x = y;tmp.y = i;q[x].push_back(tmp);tmp.x = x;tmp.y = i;q[y].push_back(tmp);}if (e1 == 0 && e2 % 2){printf("-1\n");return 0;}int start = max(e1, 1);dfs(start);for (i = 1;i <= m;i++){if (flag[i])sum++;}printf("%d\n", sum);for (i = 1;i <= m;i++){if (flag[i])printf("%d\n", i);}return 0;}


原创粉丝点击