题目链接:点击打开链接
题意:
给定一个无向图
任选一个起点,使得访问每个点的次数奇偶与最后一行的输入一致
思路:
选一个奇数点作为起点
dfs树一下,若子节点不满足则先走到子节点再回来
如此就能保证所有子节点合法
这样dfs结束后最多只有根节点不满足,随便找一个与根相连的点调整一下。
#include <stdio.h> #include <string.h> #include <iostream> #include <math.h> #include <queue> #include <set> #include <algorithm> #include <stdlib.h> using namespace std; #define ll int #define N 100005 #define inf 10000009 vector<int>G[N],ans, one, tmp; int n, m; int a[N], st, dis[N], pre[N]; void go(int u, int v, vector<int>&x){// v - u x.push_back(v); while(1){ v = pre[v]; x.push_back(v); if(v==u)return ; } } int vis[N], hehe[N]; void dfs(int u, int fa){ hehe[u] = fa; ans.push_back(u); vis[u] ^= 1; for(int i = 0; i < G[u].size(); i++) if(hehe[G[u][i]]==0) { dfs(G[u][i], u); if(a[G[u][i]] != vis[G[u][i]]) { ans.push_back(u); ans.push_back(G[u][i]); vis[G[u][i]]^=1; vis[u] ^= 1; } if(ans[ans.size()-1] != u){ans.push_back(u); vis[u]^=1;} } } void input(){ one.clear(); for(int i = 0; i <= n; i++)G[i].clear(); while(m--){ int u, v; scanf("%d %d",&u,&v); G[u].push_back(v); G[v].push_back(u); } st = -1; for(int i = 1; i <= n; i++){ scanf("%d",&a[i]); if(a[i]) { if(st==-1)st = i; one.push_back(i); } } } int main(){ int i, j, u, v; while(~scanf("%d %d",&n,&m)) { input(); if(st == -1) {puts("0");continue;} if(one.size()==1){printf("1\n%d\n", st);continue;} ans.clear(); memset(vis,0,sizeof vis); memset(hehe, 0, sizeof hehe); hehe[st] = st; dfs(st, st); if(a[st]!=vis[st]){ ans.push_back(G[st][0]); ans.push_back(st); ans.push_back(G[st][0]); } bool ok = false; for(i = 1; i <= n; i++)if(a[i] && hehe[i] == 0)ok = true; if(ok){puts("-1");continue;} printf("%d\n",ans.size()); for(i = 0; i < ans.size(); i++)printf("%d ",ans[i]);puts(""); //memset(a, 0, sizeof a); for(i = 0; i < ans.size(); i++)a[ans[i]]^=1; for(i = 1; i <=n ;i++)printf("%d ", a[i]);puts(""); } return 0; }
Codeforces 453C Little Pony and Summer Sun Celebration dfs树上构造,布布扣,bubuko.com
时间: 2024-10-06 09:59:56