前言
走远了走远了…
一直在想翻转一条链的奇偶性怎么做,但没有意识到最后一定是个菊花。
解析
一状态就是走一个欧拉回路,合法性更容易刻画,所以考虑反过来想,如何用状态二的走法删去一些边,使得剩下的图存在欧拉路径。
那么状态二的走法是啥勒?
由于最后必须把边删空,感性理解一下,状态二走出的图必然是一个菊花。
所以直接对每个点作为菊花中心讨论一下就行了。由于可能剩下的图不联通,还需要暴力跑欧拉路判合法。
代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
#define debug(...) fprintf(stderr,__VA_ARGS__)
#define ok debug("ok\n")
inline ll read(){
ll x(0),f(1);char c=getchar();
while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
while(isdigit(c)){x=(x<<1)+(x<<3)+c-'0';c=getchar();}
return x*f;
}
const int N=6050;
const int mod=998244353;
ll n,m,k;
inline ll ksm(ll x,ll k,int mod){
ll res(1);
while(k){
if(k&1) res=x*res%mod;
x=x*x%mod;
k>>=1;
}
return res;
}
struct node{
int to,nxt,id;
}p[N<<1];
int fi[N],cur[N],ecnt;
inline void addline(int x,int y,int id){
p[++ecnt]=(node){y,fi[x],id};fi[x]=ecnt;
return;
}
int zhan[N],top;
int du[N];
bool vis[N];
void dfs(int x){
//debug("x=%d\n",x);
for(int i=cur[x];~i;i=cur[x]){
cur[x]=p[i].nxt;
if(vis[p[i].id]) continue;
vis[p[i].id]=1;
dfs(p[i].to);
}
zhan[++top]=x;
}
void init(){
for(int i=1;i<=n;i++) cur[i]=fi[i];
memset(vis,0,sizeof(vis));
top=0;
}
int cnt,rt;
inline void calc(int x,int ban,int e){
init();
--e;
for(int i=fi[x];~i;i=p[i].nxt){
int to=p[i].to;
if(!(du[to]&1)) continue;
if(to==ban) continue;
vis[p[i].id]=1;
}
dfs(x);
if(top-1+e==m){
printf("%d\n",top+1+2*e);
for(int i=1;i<=top;i++) printf("%d ",zhan[i]);
printf("-1 ");
for(int i=fi[x];~i;i=p[i].nxt){
int to=p[i].to;
if(to==ban) continue;
if(du[to]&1) printf("%d %d ",to,x);
}
exit(0);
}
}
inline void work(int x){
int num=du[x]&1,e(0);
for(int i=fi[x];~i;i=p[i].nxt){
int to=p[i].to;
num+=(du[to]&1);
e+=(du[to]&1);
}
if(num==cnt){
for(int i=fi[x];~i;i=p[i].nxt){
int to=p[i].to;
if(du[to]&1) calc(x,to,e);
}
}
if(num>=cnt-1){
init();
//ok;
for(int i=fi[x];~i;i=p[i].nxt){
int to=p[i].to;
if(du[to]&1) vis[p[i].id]=1;
}
dfs(x);
if(top-1+e==m){
//printf("top=%d e=%d\n",top,e);
printf("%d\n",top+1+2*e);
for(int i=1;i<=top;i++) printf("%d ",zhan[i]);
printf("-1 ");
for(int i=fi[x];~i;i=p[i].nxt){
int to=p[i].to;
if(du[to]&1) printf("%d %d ",to,x);
}
exit(0);
}
}
return;
}
signed main(){
#ifndef ONLINE_JUDGE
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
#endif
memset(fi,-1,sizeof(fi));ecnt=-1;
cnt=-1;
n=read();m=read();
for(int i=1;i<=m;i++){
int x=read(),y=read();
addline(x,y,i);
addline(y,x,i);
du[x]++;
du[y]++;
}
cnt=0,rt=1;
for(int i=1;i<=n;i++){
if(du[i]&1){
++cnt;
rt=i;
}
}
if(cnt<=2){
init();
dfs(rt);
printf("%d\n",top);
while(top) printf("%d ",zhan[top--]);
return 0;
}
for(int i=1;i<=n;i++) work(i);
puts("0");
return 0;
}
/*
*/