## codeforces CF36E Two Paths 欧拉回路 转

o
osc_1ee7cxmx

$\rightarrow$ 戳我进CF原题

## <center>E. Two Paths</center>

<center>time limit per test: 2 seconds</center> <center>memory limit per test: 64 megabytes</center> <center>input: input.txt</center> <center>output: output.txt</center>

Once archaeologists found $m$ mysterious papers, each of which had a pair of integers written on them. Ancient people were known to like writing down the indexes of the roads they walked along, as « $a \quad b$ » or « $b \quad a$ » , where $a,b$ are the indexes of two different cities joint by the road . It is also known that the mysterious papers are pages of two travel journals (those days a new journal was written for every new journey). 　 During one journey the traveler could walk along one and the same road several times in one or several directions but in that case he wrote a new entry for each time in his journal. Besides, the archaeologists think that the direction the traveler took on a road had no effect upon the entry: the entry that looks like « $a \quad b$ » could refer to the road from $a$ to $b$ as well as to the road from $b$ to $a$ . 　 The archaeologists want to put the pages in the right order and reconstruct the two travel paths but unfortunately, they are bad at programming. That’s where you come in. Go help them!

### Input

The first input line contains integer $m (1 \le m \le 10000)$. Each of the following m lines describes one paper. Each description consists of two integers $a,b ( 1\le a,b \le 10000,a \not= b)$ .

### Output

In the first line output the number $L_i$ . That is the length of the first path, i.e. the amount of papers in its description. In the following line output $L_1$ space-separated numbers — the indexes of the papers that describe the first path. In the third and fourth lines output similarly the length of the second path $L_2$ and the path itself. Both paths must contain at least one road, i.e. condition $L_1>0$ and $L_2>0$ must be met. The papers are numbered from $1$ to $m$ according to the order of their appearance in the input file. The numbers should be output in the order in which the traveler passed the corresponding roads. If the answer is not unique, output any. 　 If it’s impossible to find such two paths, output «-1». 　 Don’t forget that each paper should be used exactly once, i.e $L_1+L_2=m$ .

### Examples

#### input1

 2
4 5
4 3


####output1

 1
2
1
1


#### input2

 1
1 2


#### output2

 -1


## 题目大意

• 在无向图中找到两条路径，一共经过每条边恰好一次。

• $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 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);
if(!vis[e[i].v]) dfs1(e[i].v);
}
int cut,top,s[maxn];
bool used[maxn],pr4;
void dfs2(int u){
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];
}
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.size()==0) cnt2st=i;
}
if(pr4){
++m;
dfs2(pr);
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.size()) dfs2(pr);
else dfs2(minu);
if(cnt==2){
cut=top;
if(pr.size()) dfs2(pr);
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);
printf("\n%d\n",m-1);
for(int i=2;i<=m;++i) printf("%d ",s[i]);
}
}
return 0;
}

o

### osc_1ee7cxmx #### 暂无文章

setTimeout还是setInterval？ - setTimeout or setInterval?

29分钟前
5
0

59分钟前
9
0
Python的__init__和self是做什么的？ - What __init__ and self do on Python?

javail

15
0
OSChina 周五乱弹 —— 你大妈还是你大妈

Osc乱弹歌单（2020）请戳（这里） 【今日歌曲】 @watergood：是时候分享一波我的这张纯音乐歌单了，过去的五年多时间里，我陆陆续续地把听到的好听的纯音乐添加了进去，目前一共65首，相信总...

25
0
ftp-ftps-sftp的关系

Ftp FTP 是File Transfer Protocol（文件传输协议）的英文简称，而中文简称为“文传协议”。用于Internet上的控制文件的双向传输。同时，它也是一个应用程序（Application）。基于不同的操作...

12
0 