小米:有網店在銷售假冒“米家防飛濺指甲刀”等,已向公安機關報案
阿新 • • 發佈:2021-11-09
前言
屑黑題。
【題目傳送門】
題解
構造題。
不需要想的太過於複雜,如果一個勁只想著怎麼走讓某個點達到目標,這題就做不出來了。
構造題,先瞎搞,再看看能不能得到答案。
先按照 DFS 生成一個樹,就構造出來了每個點經過的次數的一種方案。
考慮怎麼讓它合法,如果回溯的時候發現 \(u\) 還不合法,就在 \(u,fa\) 之間橫跳一次,\(u\) 就合法了。往上就以此類推。
注意特判根節點的情況,同時由於圖不聯通,要選一個經過奇數次的點作為起點(根)。
程式碼
#include<bits/stdc++.h> using namespace std; #define ll long long #define FCC fclose(stdin),fclose(stdout) const int INF = 0x3f3f3f3f,N = 1e5+10; inline ll read() { ll ret=0;char ch=' ',c=getchar(); while(!(c>='0'&&c<='9')) ch=c,c=getchar(); while(c>='0'&&c<='9') ret=(ret<<1)+(ret<<3)+c-'0',c=getchar(); return ch=='-'?-ret:ret; } int n,m,head[N],ecnt=-1,ans[N<<2],tot,w[N]; bool vis[N]; void init_edge(){memset(head,-1,sizeof(head)),ecnt=-1;} struct edge { int nxt,to; }a[N<<1]; inline void add_edge(int x,int y) { a[++ecnt]=(edge){head[x],y}; head[x]=ecnt; } void dfs(int u,int fa) { vis[u]=1,w[u]^=1,ans[++tot]=u; for(int i=head[u];~i;i=a[i].nxt) { int v=a[i].to; if(v==fa||vis[v]) continue; dfs(v,u); ans[++tot]=u; w[u]^=1; } if(w[u]) w[u]^=1,ans[++tot]=fa,w[fa]^=1,ans[++tot]=u; } int main() { init_edge(); n=read(),m=read(); for(int i=1;i<=m;i++) { int u=read(),v=read(); add_edge(u,v),add_edge(v,u); } int s=0; for(int i=1;i<=n;i++) { w[i]=read(); if(w[i]) s=i; } if(!s) return puts("0"),0; // printf("s=%d\n",s); dfs(s,0); for(int i=1;i<=n;i++) if(!vis[i]&&w[i]) return puts("-1"),0; if(ans[tot-1]==0&&tot>=3) tot-=3; printf("%d\n",tot); for(int i=1;i<=tot;i++) printf("%d ",ans[i]); return 0; }