【Codeforces Beta Round #36】Codeforces 36E Two Paths
2016-12-04 19:16
597 查看
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 b» or
«b 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 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 ≤ m ≤ 10000). Each of
the following m lines describes one paper. Each description consists
of two integers a, b (1 ≤ a, b ≤ 10000, a ≠ b).
Output In the first line output the number L1. That is the length of
the first path, i.e. the amount of papers in its description. In the
following line output L1 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 L2 and the path itself.
Both paths must contain at least one road, i.e. condition L1 > 0 and
L2 > 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
L1 + L2 = m.
分类讨论比较麻烦。
如果有多于两个联通块或者只有一条边,一定无解。
如果有两个联通块,那么分别求欧拉路。
如果有一个联通块,如果本身就有欧拉路直接求出然后随意断开。此外如果入度为奇数的点【以下简称奇点】有4个,还可以两笔画。做法是连接两个奇点,求剩下的两个奇点的欧拉路,再从添加的这条边断开。
求欧拉路可以用Fleury算法dfs一遍解决。
pair of integers written on them. Ancient people were known to like
writing down the indexes of the roads they walked along, as «a b» or
«b 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 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 ≤ m ≤ 10000). Each of
the following m lines describes one paper. Each description consists
of two integers a, b (1 ≤ a, b ≤ 10000, a ≠ b).
Output In the first line output the number L1. That is the length of
the first path, i.e. the amount of papers in its description. In the
following line output L1 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 L2 and the path itself.
Both paths must contain at least one road, i.e. condition L1 > 0 and
L2 > 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
L1 + L2 = m.
分类讨论比较麻烦。
如果有多于两个联通块或者只有一条边,一定无解。
如果有两个联通块,那么分别求欧拉路。
如果有一个联通块,如果本身就有欧拉路直接求出然后随意断开。此外如果入度为奇数的点【以下简称奇点】有4个,还可以两笔画。做法是连接两个奇点,求剩下的两个奇点的欧拉路,再从添加的这条边断开。
求欧拉路可以用Fleury算法dfs一遍解决。
#include<cstdio> #include<cstring> #include<algorithm> #include<vector> using namespace std; vector<pair<int,int> > to[10010]; int fa[10010],bel[10010],size[10010],sta[10010],top,m,n,clo; bool vis[10010]; int find(int x) { return x==fa[x]?x:fa[x]=find(fa[x]); } bool init() { int i,x,y; scanf("%d",&m); for (i=1;i<=10000;i++) fa[i]=i; for (i=1;i<=m;i++) { scanf("%d%d",&x,&y); n=max(n,max(x,y)); fa[find(x)]=find(y); to[x].push_back(make_pair(y,i)); to[y].push_back(make_pair(x,i)); } for (i=1;i<=n;i++) if (to[i].size()&&fa[i]==i) bel[i]=++clo; for (i=1;i<=n;i++) if (to[i].size()) bel[i]=bel[find(i)]; for (i=1;i<=n;i++) if (to[i].size()) size[bel[i]]+=to[i].size(); for (i=1;i<=clo;i++) size[i]/=2; } void dfs(int u) { int i,v,x; for (i=0;i<to[u].size();i++) if (!vis[x=to[u][i].second]) { v=to[u][i].first; vis[x]=1; dfs(v); sta[++top]=x; } } void out1() { int i; printf("1\n%d\n%d\n",sta[1],m-1); for (i=2;i<=m;i++) printf("%d%c",sta[i],i==m?'\n':' '); } void out2() { int i,p; for (p=1;;p++) if (sta[p]==m+1) break; printf("%d\n",p-1); for (i=1;i<p;i++) printf("%d%c",sta[i],i==p-1?'\n':' '); printf("%d\n",m-p+1); for (i=p+1;i<=m+1;i++) printf("%d%c",sta[i],i==m+1?'\n':' '); } void solve1() { int i,x,y,z,cnt=0; for (i=1;i<=n;i++) if (to[i].size()&1) cnt++; switch (cnt) { case 0: for (i=1;i<=n;i++) if (to[i].size()) { dfs(i); break; } break; case 2: for (i=1;i<=n;i++) if (to[i].size()&1) { dfs(i); break; } break; case 4: { x=y=-1; for (i=1;i<=n;i++) if (to[i].size()&1) { if (x==-1) x=i; else { y=i; break; } } to[x].push_back(make_pair(y,m+1)); to[y].push_back(make_pair(x,m+1)); size[bel[x]]++; for (i=1;i<=n;i++) if (to[i].size()&1) { dfs(i); break; } break; } default: printf("-1\n"); return; break; } if (cnt==4) out2(); else out1(); } void out0() { int i; printf("%d\n",top); for (i=1;i<=top;i++) printf("%d%c",sta[i],i==top?'\n':' '); top=0; } void solve2() { int i,cnt1=0,cnt2=0; for (i=1;i<=n;i++) if (to[i].size()&1) { if (bel[i]==1) cnt1++; else cnt2++; } if (cnt1>2||cnt2>2) { printf("-1\n"); return; } if (!cnt1) { for (i=1;i<=n;i++) if (to[i].size()&&bel[i]==1) { dfs(i); break; } } else { for (i=1;i<=n;i++) if (to[i].size()&1&&bel[i]==1) { dfs(i); break; } } out0(); if (!cnt2) { for (i=1;i<=n;i++) if (to[i].size()&&bel[i]==2) { dfs(i); break; } } else { for (i=1;i<=n;i++) if (to[i].size()&1&&bel[i]==2) { dfs(i); break; } } out0(); } int main() { freopen("input.txt","r",stdin); freopen("output.txt","w",stdout); init(); if (m==1) { printf("-1\n"); return 0; } switch (clo) { case 1:solve1();break; case 2:solve2();break; default: printf("-1\n");break; } }
相关文章推荐
- codeforces 36E Two Paths
- CodeForces 197A
- CodeForces 579A - Raising Bacteria
- 【CodeForces】638A - Home Numbers
- Codeforces 710E Generate a String【dp】好题!
- codeforces 528D Fuzzy Search
- CodeForces 258C Little Elephant and LCM(数学推理)
- codeforces 432C Prime Swaps
- codeforces 572D Minimization
- CodeForces 624A Save Luke(相对,数学)
- 【CodeForces】233B - Non-square Equation(思维)
- codeforces——189A——Cut Ribbon
- Codeforces 876 C Classroom Watch
- codeforces 1A Theatre Square(再来一水题)
- codeforces 351A A. Jeff and Rounding(智商题+枚举)
- Codeforces 637D Running with Obstacles (贪心)
- Codeforces 401B Sereja and Contests【水题】
- Codeforces 812C Sagheer and Nubian Market[二分]
- CodeForces - 787A The Monster
- CodeForces 432D Prefixes and Suffixes