Codeforces841D dfs+脑洞
来源:互联网 发布:网络整合营销的道与术 编辑:程序博客网 时间:2024/06/03 21:42
题目链接:http://codeforces.com/contest/841/problem/D
题意:给你一个n个点m条边的联通无向图,有重边无自环,每个点有一个权值d,d[i]={-1,0,1},要求在图中选择一些边使得对于图中的任意点 i 有度数x%2==d[i]或者d[i]==-1.
思路:考虑一条边都不选的时候,那么d[i]==1的点将不满足要求,我们就必须要给它加一条边。如果我们用dfs来维护这个过程,对于d[i]>=0的点,添边的过程实际上是d[i]取反的过程,我们从叶子结点向上搜索,对于每一棵子树u(u为父节点),如果u的子节点v d[v]==1,我们就在u和v之间连一条边,表现为d[u](d[u]!=-1)和d[v]取反,由于对一个节点进行取反并不影响他的子节点的状态,所以当我们将这个过程进行完毕后只有根节点的状态是不确定的,那么对于根节点u,如果d[u]==0或者d[u]==-1,那么此时选取的边已经符合要求,如果d[u]==1,考虑如果它的所有子节点中,存在一点x d[x]==-1,那么我们遍历从x到u的路径,并沿途取反,此时这条路径上只有u的状态会发生改变,其他的状态均不会发生改变,此时d[u]==0,符合题意要求,输出即可。因此输出-1的条件就是不存在一个点i d[i]==-1(题目保证图联通)
参考题解传送门:点击打开链接
代码:
#include <iostream>#include <string.h>#include <stdlib.h>#include <stdio.h>#include <algorithm>#include <cstdio>#include <time.h>#include <queue>#include <set>#include <map>#include <stack>#include <math.h>//#include <bits/stdc++.h>#define ll long long#define int64 long long#define mem(x,y) memset(x,y,sizeof(x))#define ull unsigned long long#define pb push_back#define INF 0x3f3f3f3f#define lson l, mid, rt<<1#define rson mid+1, r, rt<<1|1#define pi 3.141592653589793238462#define stdio std::ios::sync_with_stdio(false)using namespace std;inline bool nextDouble(double &num) { char in; double Dec = 0.1; bool IsN = false, IsD = false; in = getchar(); if (in == EOF) return false; while (in != '-' && in != '.' && (in < '0' || in > '9')) in = getchar(); if (in == '-') { IsN = true; num = 0; } else if (in == '.') { IsD = true; num = 0; } else num = in - '0'; if (!IsD) { while (in = getchar(), in >= '0' && in <= '9') { num *= 10; num += in - '0'; } } if (in != '.') { if (IsN) num = -num; return true; } else { while (in = getchar(), in >= '0' && in <= '9') { num += Dec * (in - '0'); Dec *= 0.1; } } if (IsN) num = -num; return true;}inline bool nextInt(int &num) { char in; bool IsN = false; in = getchar(); if (in == EOF) return false; while (in != '-' && (in < '0' || in > '9')) in = getchar(); if (in == '-') { IsN = true; num = 0; } else num = in - '0'; while (in = getchar(), in >= '0' && in <= '9') { num *= 10, num += in - '0'; } if (IsN) num = -num; return true;}inline bool nextLong(ll &num) { char in; bool IsN = false; in = getchar(); if (in == EOF) return false; while (in != '-' && (in < '0' || in > '9')) in = getchar(); if (in == '-') { IsN = true; num = 0; } else num = in - '0'; while (in = getchar(), in >= '0' && in <= '9') { num *= 10, num += in - '0'; } if (IsN) num = -num; return true;}const int maxn = 3e5 + 5;const int maxm = 1e3 + 5;const int mod = 1e9 + 7;const int seed = 10007;const double eps = 1e-6;int n, m;typedef pair<int, int> P;int d[maxn];vector<P> g[maxn];bool vis[maxn], select[maxn];P fa[maxn];void dfs(int u) { for (int i = 0; i < (int)g[u].size(); i++) { int v = g[u][i].first; int id = g[u][i].second; if (vis[v]) continue; vis[v] = 1; fa[v] = P(u, id); dfs(v); if (d[v] == 1) { d[v] = 0; select[id] ^= 1; if (d[u] != -1) d[u] ^= 1; } }}int main() { stdio; cin >> n >> m; int flag = -1; for (int i = 1; i <= n; i++) { cin >> d[i]; if (d[i] == -1) flag = i; } int a, b; for (int i = 1; i <= m; i++) { cin >> a >> b; g[a].pb(P(b, i)); g[b].pb(P(a, i)); } mem(vis, 0); mem(select, 0); vis[1] = 1; dfs(1); if (d[1] == 1) { if (flag == -1) { cout << -1 << endl; return 0; } else { while (flag != 1) { select[fa[flag].second] ^= 1; flag = fa[flag].first; } } } int ans = 0; for (int i = 1; i <= m; i++) { if (select[i]) ans++; } cout << ans << endl; for (int i = 1; i <= m; i++) { if (select[i]) cout << i << " "; } cout << endl; return 0;}
阅读全文
0 0
- Codeforces841D dfs+脑洞
- DFS
- DFS
- dfs
- dfs
- dfs
- dfs
- DFS
- DFS
- dfs
- DFS
- DFS
- DFS
- dfs
- DFS
- dfs
- dfs
- dfs
- hdu6134-莫比乌斯反演+思维
- pom文件元素含义
- hdu6150 构造题_ccpc
- linux扩展逻辑卷大小
- ABAP学习笔记一(KISS)
- Codeforces841D dfs+脑洞
- 致橡树
- Mirrored String II 【最长回文子串】
- Qt入门之信号与槽机制
- 76. Minimum Window Substring
- I.SPY.Mystery.v1.0-T
- 树莓派3 搭建bt下载机---利用 aria2
- STL map的使用
- ubuntu下php版本切换