CF453C Little Pony and Summer Sun Celebration题解
CF453C Little Pony and Summer Sun Celebration
洛谷链接:https://www.luogu.com.cn/problem/CF453C
CF链接:https://codeforces.com/problemset/problem/453/C
前言:
小马特辑!i了i了
题意:
给出一张 \(N\) 个点 \(M\) 条边的无向图,有些点要求经过奇数次,有些点要求经过偶数次。要求寻找一条满足要求的路径,且该路径长度不超过点数的四倍。
\(0\leq N,M\leq100000\)
题解:
求出图的任意生成树,任意定根,搜索。很明显,如果这样的话,叶子必定只访问一次,非叶子结点必定只访问两次。
如果非叶子节点要求访问奇数次,就会有问题,这时只要让它的父亲多遍历这个点一次即可。
如果这个点是树根,只要对一个奇数点回溯即可。
Code:
#include<iostream>
#include<cstdio>
using namespace std;
#define FOR(i,a,b) for(int i=a;i<=b;i++)
#define REP(i,a,b) for(int i=a;i>=b;i--)
inline int read()
{
int x=0,f=1;
char ch=getchar();
while(!isdigit(ch))
{
if(ch=='-')f=-1;
ch=getchar();
}
while(isdigit(ch))
{
x=x*10+ch-48;
ch=getchar();
}
return x*f;
}
inline void write(int x)
{
if(x<0) putchar('-'),write(-x);
else
{
if(x>9)write(x/10);
putchar('0'+x%10);
}
}
inline void writeputs(int x)
{
write(x);
putchar('\n');
}
inline void writeputchar(int x)
{
write(x);
putchar(' ');
}
int n,m,tot,fir[100005],root,ans[400005],ANS;bool a[100005],vis[100005];
struct edge
{
int nxt,to;
}e[200005];
inline void add(int u,int v)
{
e[++tot]={fir[u],v};
fir[u]=tot;
}
void dfs(int u,int dad)
{
vis[u]=1,a[u]^=1,ans[++ANS]=u;
for(int i=fir[u];i;i=e[i].nxt)
{
int v=e[i].to;
if(!vis[v]) dfs(v,u),ans[++ANS]=u,a[u]^=1;
}
if(a[u]) ans[++ANS]=dad,a[dad]^=1,ans[++ANS]=u,a[u]^=1;
}
int main()
{
n=read(),m=read();
FOR(i,1,m)
{
int u,v;
u=read();
v=read();
add(u,v);
add(v,u);
}
FOR(i,1,n)
{
a[i]=read();
if(a[i]&&!root)root=i;
}
if(root!=0)
{
dfs(root,-1);
FOR(i,1,n)
if(!vis[i]&&a[i])
{
write(-1);
return 0;
}
}
if(ANS>1&&ans[ANS-1]==-1) ANS-=3;
writeputs(ANS);
FOR(i,1,ANS) writeputchar(ans[i]);
return 0;
}