Codeforces 841D Leha and another game about graph(dfs)

来源:互联网 发布:照相变萌软件 编辑:程序博客网 时间:2024/06/05 07:37

题目Codeforces 841D


题意:给定一n个结点m条边的连通图,第i个结点有值di,di为0、1、-1其中之一。让选定边的子集,使选择后图中每个结点满足:若di≠-1,则di等于结点度数mod2,给出任一种选法。


思路:考虑全部边都不选的情况,此时di=0和di=-1的结点满足条件。为满足di=1的结点,需向其它结点连接一条边,另一结点di取反。将其它结点看作此结点的父亲,则总可以改变儿子与父亲之间边的状态来满足儿子结点的di值,可利用dfs使除根以外的所有结点满足要求。最后判断根节点,若di=1,则需要从任意di=-1的结点中选一个,其与根节点之间的路径全部取反,此时除根节点与这一节点以外,中途任何节点度数mod2均不受影响,可满足要求。若没有di=-1的子结点,则无解。

#include <cstdio>#include <cstring>#include <queue>#include <algorithm>#include <cmath>#include <vector>#include <iostream>#include <stack>#include <set>#include <map>using namespace std;const int MAX=4e5+5;int n,m,ans;int d[MAX],vis[MAX],select[MAX]; pair<int,int> f[MAX];vector<pair<int,int>> E[MAX];void dfs(int u,int fa){int i;int v,id;for(i=0;i<E[u].size();i++){v=E[u][i].first;id=E[u][i].second;if(v==fa||vis[v])    continue;vis[v]=1;f[v]=make_pair(u,id);dfs(v,u);if(d[v]==1){d[v]=0;select[id]^=1;if(d[u]!=-1)    d[u]^=1;}}}int main(){int i;int u,v,node=0;scanf("%d%d",&n,&m);for(i=1;i<=n;i++){scanf("%d",&d[i]);if(d[i]==-1)    node=i;}for(i=1;i<=m;i++){scanf("%d%d",&u,&v);E[u].push_back(make_pair(v,i));E[v].push_back(make_pair(u,i));}dfs(1,0);if(d[1]==1){if(node==0){printf("-1\n");return 0;}while(node!=1){select[f[node].second]^=1;node=f[node].first;}}for(i=1;i<=m;i++)    if(select[i])        ans++;printf("%d\n",ans);for(i=0;i<=m;i++)    if(select[i])        printf("%d%c",i,i==m?'\n':' ');        return 0;} 


原创粉丝点击