题目:http://codeforces.com/contest/36/problem/E

给定一张无向图,要求输出两条欧拉路覆盖所有边;

分类讨论,首先判-1:有两个以上连通块 / 有四个以上奇度数点 / 只有一条边 / 有两个连通块而其中一个连通块里有四个奇度数点 (/ 有连通块里有奇数个奇度数点);

然后分两个连通块和一个连通块的情况进行 dfs 找欧拉路(模板 dfs );

注意可能没有奇度数的点,也就是有欧拉回路,所以不仅找奇度数点进行 dfs ,还要在那之后 dfs 仍然没有被走过的点;

明明是模仿题解写的竟然还调了两小时...码力++...

代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int const maxn=;
int n,m,d[maxn],ans[maxn],tot,fa[maxn],cnt,c[maxn],hd[maxn],ct=;
bool vis[maxn],used[maxn];
struct N{
int to,nxt;
N(int t=,int n=):to(t),nxt(n) {}
}ed[maxn<<];
void add(int x,int y){ed[++ct]=N(y,hd[x]); hd[x]=ct;}
int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);}
void dfs(int x)
{
vis[x]=;
for(int i=hd[x];i;i=hd[x])
{
hd[x]=ed[i].nxt;
if(used[i>>])continue;
used[i>>]=; dfs(ed[i].to); ans[++tot]=(i>>);
}
}
int main()
{
freopen("input.txt","r",stdin);
freopen("output.txt","w",stdout);
n=; scanf("%d",&m);//不能是 n=10005
for(int i=;i<=n;i++)fa[i]=i;//!!
for(int i=,x,y;i<=m;i++)
{
scanf("%d%d",&x,&y);
add(x,y); add(y,x); d[x]++; d[y]++;
if(find(x)!=find(y))fa[find(x)]=find(y);
}
for(int i=;i<=n;i++) if(d[i]&) c[find(i)]++;
for(int i=;i<=n;i++) if(c[i]&){printf("-1\n"); return ;}
for(int i=,sum=;i<=n;i++)
{
if(d[i])cnt+=(i==find(i));
if(c[i])sum+=c[i];
if(sum>){printf("-1\n"); return ;}
}
if(cnt>){printf("-1\n"); return ;}
if(cnt==)
{
for(int i=;i<=n;i++) if(c[i]==){printf("-1\n"); return ;}
for(int i=;i<=n;i++)
if(!vis[i]&&(d[i]&))
{
tot=; dfs(i); printf("%d\n",tot);
for(int j=tot;j;j--)printf("%d ",ans[j]); printf("\n");
}
for(int i=;i<=n;i++)//欧拉回路
if(!vis[i]&&d[i])
{
tot=; dfs(i); printf("%d\n",tot);
for(int j=tot;j;j--)printf("%d ",ans[j]); printf("\n");
}
}
else
{
bool fl=;
for(int i=;i<=n;i++) if(c[i]==)fl=;
if(fl)
{
for(int i=;i<=n;i++) if(d[i]&)
{
for(int j=i+;j<=n;j++)
if(d[j]&){d[i]++; d[j]++; add(i,j); add(j,i); break;}
break;
}
for(int i=;i<=n;i++)
if(!vis[i]&&(d[i]&)){tot=; dfs(i); break;}
for(int i=;i<=tot;i++) if(ans[i]==m+)
{
printf("%d\n",i-);
for(int j=;j<i;j++)printf("%d ",ans[j]); printf("\n");
printf("%d\n",tot-i);
for(int j=i+;j<=tot;j++)printf("%d ",ans[j]);
break;
}
}
else
{
for(int i=;i<=n;i++)
if(!vis[i]&&(d[i]&)){tot=; dfs(i);}
for(int i=;i<=n;i++)//欧拉回路
if(!vis[i]&&d[i]){tot=; dfs(i);}
if(tot<=){printf("-1\n"); return ;}//只有一条边
printf("1\n%d\n%d\n",ans[],tot-);
for(int i=;i<=tot;i++)printf("%d ",ans[i]);
}
}
return ;
}

CF36 E Two Paths——欧拉(回)路的更多相关文章

  1. 拓扑排序&&欧拉(回)路

    摘要:最近是不适合写代码么?忘记初始化wa到死<_=_=_>.唔--最近在学习图论,从基础搞起,先搞了拓扑排序和欧拉(回)路. Part 0. 拓扑排序 ==挖坑== Part 1. 欧拉 ...

  2. Codeforces 871D Paths (欧拉函数 + 结论)

    题目链接  Round  #440  Div 1  Problem D 题意   把每个数看成一个点,如果$gcd(x, y) \neq 1$,则在$x$和$y$之间连一条长度为$1$的无向边.   ...

  3. Poj 2337 Catenyms(有向图DFS求欧拉通路)

    题意: 给定n个单词, 问是否存在一条欧拉通路(如acm,matal,lack), 如果存在, 输出字典序最小的一条. 分析: 这题可以看作http://www.cnblogs.com/Jadon97 ...

  4. POJ 2337 Catenyms(有向图的欧拉通路)

    题意:给n个字符串(3<=n<=1000),当字符串str[i]的尾字符与str[j]的首字符一样时,可用dot连接.判断用所有字符串一次且仅一次,连接成一串.若可以,输出答案的最小字典序 ...

  5. HDU1116 Play on Words(有向图欧拉通路)

    我把单词当作点,然后这样其实是不对的,这样就要判定是否是哈密顿通路.. 这题应该把单词的首尾单词当作点,而单词本身就是边,那样就是判定欧拉通路了. 有向图包含欧拉通路的充要条件是:首先基图连通,然后是 ...

  6. POJ 1386 有向图欧拉通路

    题意:给你一些字符串,这些字符串可以首位相接(末位置如果和另一个字符串的首位置相同的话就可以相连) .然后问你是否可以全部连起来. 思路:就是取出每个字符串的首尾位置,然后求出出度和入度,根据有向欧拉 ...

  7. UVA 10129-Play on Words(欧拉通路)

    题意:给N个单词,判断是否单词首尾(前一个单词的尾字符与后一个单词的头字符相同)相连能否形成一条链. 解析:找欧拉通路(欧拉回路或是欧拉链路),但这题事先需要并查集一下,判断是否只属于一个集合,如aa ...

  8. CodeForces - 508D Tanya and Password(欧拉通路)

    Description While dad was at work, a little girl Tanya decided to play with dad characters. She has ...

  9. POJ--1300--Door Man【推断无向图欧拉通路】

    链接:http://poj.org/problem?id=1300 题意:有n个房间.每一个房间有若干个门和别的房间相连.管家从m房间開始走.要回到自己的住处(0),问是否有一条路能够走遍全部的门而且 ...

随机推荐

  1. js统计图表插件 Echarts

    Echarts 用于制作数据统计图表,一个纯 Javascript 的图表库,快捷简便的生成统计图表. 官网:https://www.echartsjs.com/ 效果 html <!DOCTY ...

  2. go new() 和 make() 的区别

    看起来二者没有什么区别,都在堆上分配内存,但是它们的行为不同,适用于不同的类型. new(T) 为每个新的类型T分配一片内存,初始化为 0 并且返回类型为*T的内存地址:这种方法 返回一个指向类型为 ...

  3. 【原】CentOS release 6.2 安装mysql

     1.  yum update升级以后的系统版本为 [root@yl-web yl]# cat /etc/redhat-release CentOS Linux release 7.1.1503 (C ...

  4. 浅谈java浅拷贝和深拷贝

    前言:深拷贝和浅拷贝的区别是什么? 浅拷贝:被复制的对象的所有变量都含有原来对象相同的值,而所有的对其他对象的引用仍然指向原来的对象.换言之, 浅拷贝仅仅复制所考虑的对象,而不复制它所引用的对象.深拷 ...

  5. poj3061 Subsequence【尺取法】

    Description A sequence of N positive integers (10 < N < 100 000), each of them less than or eq ...

  6. TestNG超时测试

    用@Test(timeOut = XXX) 指定超时时间,单位是毫秒 package com.janson; import org.testng.annotations.Test; public cl ...

  7. 类与类之间的关系UML模型图

    关联.依赖.聚合.组合.泛化.实现 类之间可能存在以下几种关系:关联(association).依赖(dependency).聚合(Aggregation,也有的称聚集).组合(Composition ...

  8. Xshell(smarTTY)连接Linux虚拟机失败(未开放22端口)解决办法

    1.关闭防火墙: 命令:sudo ufw disable 2.安装openssh-server以及openssh-client: 命令:sudo apt-get install openssh-ser ...

  9. 51NOD 1154 回文串的划分(DP)

    思路:参考了网上,思路很清奇,借助vis[i][j]来表示从i到j是否为回文串,回文串这边是用的双重循环来写的:dp[i]用来表示以i结尾的字符串最少的回文串有多长. #include<cstr ...

  10. 【Codeforces 466B】Wonder Room

    [链接] 我是链接,点我呀:) [题意] 让你把长为a,宽为b的房间扩大(长和宽都能扩大). 使得它的面积达到6*n 问你最小的能满足要求的面积是多少 输出对应的a和b [题解] 假设a< b ...