在无向图中找到两条路径,一共经过每条边恰好一次。
$ n,m \le 10000 $
连通块个数 $ >2 $ ,无解
某个连通块奇度数点 $ >4 $ 个,无解
连通块个数 $ =2 $ 并且其中一个连通块奇度数点 $ =4 $ 个,无解
连通块个数 $ =1 $,奇度点个数 $ =4 $,在两个奇度点之间加一条虚边,求欧拉路,再断开
其他情况,直接求欧拉路或欧拉回路
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<vector>
using namespace std;
#define maxn 10005
struct edge{ int v,id,nxt; }e[maxn<<1];
int head[maxn],tot=1;
void add(int u,int v,int num){
e[++tot].v=v; e[tot].id=num; e[tot].nxt=head[u]; head[u]=tot;
}
int m,cnt,deg[maxn];
vector<int>pr[maxn];
bool vis[maxn];
void dfs1(int u){
vis[u]=1;
if(deg[u]&1) pr[cnt].push_back(u);
for(int i=head[u];i;i=e[i].nxt)
if(!vis[e[i].v]) dfs1(e[i].v);
}
int cut,top,s[maxn];
bool used[maxn],pr4;
void dfs2(int u){
for(int i=head[u];i;i=e[i].nxt)
if(!used[e[i].id]){
used[e[i].id]=1;
dfs2(e[i].v);
s[++top]=e[i].id;
if(e[i].id==m&&pr4) cut=top;
}
}
int minu=maxn,cnt2st;
bool pot[maxn];
int main(){
freopen("input.txt","r",stdin);
freopen("output.txt","w",stdout);
scanf("%d",&m);
for(int u,v,i=1;i<=m;++i){
scanf("%d %d",&u,&v);
pot[u]=pot[v]=1;
minu=min(minu,min(u,v));
++deg[u]; ++deg[v];
add(u,v,i); add(v,u,i);
}
if(m==1){ puts("-1"); return 0; }
for(int i=1;i<=10000;++i)
if(!vis[i]&&pot[i]){
++cnt;
if(cnt>2){ puts("-1"); return 0; }
if(pr4){ puts("-1"); return 0; }
dfs1(i);
if(pr[cnt].size()>4){ puts("-1"); return 0; }
if(pr[cnt].size()==4){
if(cnt>1){ puts("-1"); return 0; }
pr4=1;
}
if(cnt==2&&pr[2].size()==0) cnt2st=i;
}
if(pr4){
add(pr[1][0],pr[1][1],m+1);
add(pr[1][1],pr[1][0],m+1);
++m;
dfs2(pr[1][2]);
if(top!=m){ puts("-1"); return 0; }
printf("%d\n",cut-1);
for(int i=1;i<cut;++i) printf("%d ",s[i]);
printf("\n%d\n",m-cut);
for(int i=cut+1;i<=m;++i) printf("%d ",s[i]);
} else {
if(pr[1].size()) dfs2(pr[1][0]);
else dfs2(minu);
if(cnt==2){
cut=top;
if(pr[2].size()) dfs2(pr[2][0]);
else dfs2(cnt2st);
if(top!=m){ puts("-1"); return 0; }
printf("%d\n",cut);
for(int i=1;i<=cut;++i) printf("%d ",s[i]);
printf("\n%d\n",m-cut);
for(int i=cut+1;i<=m;++i) printf("%d ",s[i]);
} else {
if(top!=m){ puts("-1"); return 0; }
puts("1");
printf("%d ",s[1]);
printf("\n%d\n",m-1);
for(int i=2;i<=m;++i) printf("%d ",s[i]);
}
}
return 0;
}