给出一个图,求一条欧拉回路。另外加入一种模式,如果开了,则后面的是各一次删一条。
由于开了之后是各一次删一条边,那么就只能是已一个点为中心来回走,不然删不掉所有的边。因此图就变成了两部分,一个是欧拉回路全删掉,一个是以一个点为中心的星图。
枚举星图的中心,然后把他所有相邻的边删掉,如果此时奇数点大于1,那么肯定不存在,因此中心肯定是欧拉的终点(奇数点)。
有两种情况:
1. 相邻的奇数点都放在星图
如果欧拉图的奇数点等于1,该星图中心就必须也是奇数点。如果是0,则是偶数点。
2.欧拉图的奇数点为0,但是星图中心是奇数点,则需要从相邻的奇数点拿一个。
枚举相邻的奇数点,看看是否可以跑出答案。
看上去好像是O(n^2*m),但由于枚举点+枚举相邻的点,一共只会枚举m条边,时间复杂度就是O(m*m)
using namespace std;
//int mod = 998244353;
int mod = 1e9+7;
int get_min(int a, int b){
if(a==-1) return b;
if(b==-1) return a;
return min(a,b);
}
struct Edge{
int a,b,c,next;
int v;
Edge(){v = 0;}
Edge(int a, int b, int c, int next):a(a),b(b),c(c),next(next){v = 0;}
}e[N];
int p[N];
int tot;
int n,m;
void add(int a, int b){
e[tot] = Edge(a,b,0,p[a]);
p[a] = tot++;
}
vector<int> g[N];
int d[N], dd[N], v[N];
vector<int> ans;
void dfs(int t){
for(int i = p[t]; i !=-1; i = e[i].next){
if(e[i].c)continue;
e[i].c = 1;
e[i^1].c = 1;
dfs(e[i].b);
}
ans.pb(t);
}
int sol(int idx){
int c = 0;
for(int i = 0; i < tot; i +=2){
if(e[i].c==2)continue;
e[i].c = 0;
e[i^1].c = 0;
c++;
}
dfs(idx);
if(ans.size() != c + 1){
ans.clear();
return 0;
}
return 1;
}
bool check(int idx){
int dn = 0;
for(int i = 1; i <=n; ++i){
if(d[i]%2 && i !=idx){
++dn;
}
dd[i] = d[i];
}
for(int i = 0; i <tot; i++){
e[i].c = 0;
}
int dn2 = 0;
for(int i = p[idx]; i !=-1; i = e[i].next){
int u = e[i].b;
if(dd[u]%2){
dn2++;
}
}
if(dn-dn2>=2){
return 0;
}
if(dn-dn2<=1){
vector<int> x,nd;
for(int i = p[idx]; i !=-1; i = e[i].next){
int u = e[i].b;
if(dd[u]%2){
dd[u]--;
dd[idx]--;
e[i].c = 2;
e[i^1].c = 2;
nd.pb(u);
x.pb(i);
}
}
ans.clear();
if((dn-dn2==0&&dd[idx]%2==0)||(dn-dn2==1&&dd[idx]%2)){
if(sol(idx)){
if(nd.size()){
ans.pb(-1);
for(int d : nd){
ans.pb(d);
ans.pb(idx);
}
}
return 1;
}
}
if(dn-dn2==0 && dd[idx]%2==0){
for(int i : x){
e[i].c = 0;
e[i^1].c = 0;
ans.clear();
if(sol(idx)){
if(nd.size()>1){
ans.pb(-1);
for(int d : nd){
if(d==e[i].b)continue;
ans.pb(d);
ans.pb(idx);
}
}
return 1;
}
e[i].c = 2;
e[i^1].c = 2;
}
}
}
return 0;
}
int main(){
cin>>n>>m;
tot = 0;
_clr(p);
fr(i,0,m){
int u,v;
cin>>u>>v;
add(u,v);
add(v,u);
++d[u];
++d[v];
}
for(int i = 1; i <=n;++i){
if(check(i)){
break;
}
}
cout<<ans.size()<<endl;
for(int t : ans){
printf("%d ",t);
}
pf("\n");
}