CF36E Two Paths (欧拉回路+构造)
题目大意:给你一张可能有重边的不保证联通的无向图,现在要在这个图上找出两条路径,恰好能覆盖所有边一次,根据边的编号输出方案,无解输出-1
一道很不错的欧拉路径变形题
首先要知道关于欧拉路径的一种算法:Hierholzer算法
欧拉路径与欧拉回路
我们称度为奇数的点为奇点,度为偶数的点为偶点
从一个点开始走,把其它所有边都走了一遍,叫欧拉路径
从一个点开始走,把其它所有边都走了一遍又回到了这个点,叫欧拉回路
如果图中存在欧拉回路,所有点均为偶点,画画图就明白了
如果图中不存在或仅存在两个奇点,那么这个图存在欧拉路径,且路径的起点终点一定分别是这两个奇点。把起点终点连起来不就变成欧拉回路了么
欧拉回路一定是欧拉路径
Hierholzer算法
从图中的一个奇点开始dfs,每遍历到一条边,就在图中删去这条边(包括反向边),然后递归指向的节点
直到当前节点相连的所有边都被删掉之后,把当前节点推入一个栈中,回溯
如果原图存在欧拉回路,就能搜出欧拉回路。如果存在欧拉路径,就会搜出欧拉路径。
栈中存储的是路径的倒序点序列,而边序列就是每次递归前删掉的边构成的序列
实现比较简单
那这道题该怎么搞呢?
(1)如果图中有>2个连通块,一定无解
(2)如果只有1个连通块,分为0个奇点,2个奇点,4个奇点讨论,其它情况都是无解
0个奇点就是欧拉回路,断开其中任意一条边,把路径拆成两条就是答案
2个奇点就是欧拉路径,断开其中任意一条边,把路径拆成两条就是答案
4个奇点的话,挑两个奇点连起来,再跑欧拉路径就行啦
(3)如果有2个连通块,说明这两条路径分别在这两个连通块里
对于每个连通块而言,只能存在0个奇点和2个奇点两种情况,讨论一下就好啦
代码写得好丑啊TvT
#include <cstdio>
#include <cstring>
#include <algorithm>
#define ll long long
#define N1 20010
using namespace std; template <typename _T> void read(_T &ret)
{
ret=; _T fh=; char c=getchar();
while(c<''||c>''){ if(c=='-') fh=-; c=getchar(); }
while(c>=''&&c<=''){ ret=ret*+c-''; c=getchar(); }
ret=ret*fh;
} struct Edge{
int to[N1*],nxt[N1*],del[N1*],head[N1],cte;
void ae(int u,int v)
{ cte++; to[cte]=v; nxt[cte]=head[u]; head[u]=cte; }
}e; int n,m,num;
int inc[N1],vis[N1],use[N1],stk[N1],tp;
void dfs1(int x,int id)
{
int j,v; vis[x]=id; num++;
for(j=e.head[x];j;j=e.nxt[j])
{
v=e.to[j];
if(!vis[v]) dfs1(v,id);
}
}
void euler(int x)
{
int j,v,la=;
for(j=e.head[x];j;j=e.nxt[j])
{
if(e.del[j]) continue;
v=e.to[j]; e.del[j]=; e.del[j^]=;
euler(v); stk[++tp]=j>>;
}
}
void fkdown(){ puts("-1"); exit(); }
int odd[N1],cnt_odd; void solve0(int id,int esum)
{
int i;
for(i=;i<=n;i++) if(vis[i]==id)
{
euler(i);
if(tp<esum) fkdown();
printf("%d\n",tp);
while(tp) printf("%d ",stk[tp--]);
puts("");
break;
}
}
void solve2(int id,int esum)
{
euler(odd[]);
if(tp<esum) fkdown(); //
printf("%d\n",tp);
while(tp) printf("%d ",stk[tp--]);
puts("");
} int main()
{
freopen("input.txt","r",stdin);
freopen("output.txt","w",stdout);
scanf("%d",&m);
int i,j,x,y,cnt_compo=; n=; e.cte=;
if(m==) fkdown();
for(i=;i<=m;i++)
{
read(x), read(y), e.ae(x,y), e.ae(y,x);
inc[x]++, inc[y]++, use[x]=, use[y]=;
}
for(i=;i<=n;i++) if(use[i] && !vis[i]) cnt_compo++, dfs1(i,cnt_compo);
if(cnt_compo>) fkdown();
if(cnt_compo==){
for(i=;i<=n;i++) if(inc[i]&) odd[++cnt_odd]=i;
if(!cnt_odd){ for(i=;i<=n;i++) if(inc[i])
{
euler(i);
if(tp<m) fkdown();
printf("%d\n",tp-);
while(tp>) printf("%d ",stk[tp--]);
puts("");
puts("");
while(tp>) printf("%d ",stk[tp--]);
puts("");
break;
} }else if(cnt_odd==){ euler(odd[]);
if(tp<m) fkdown();
printf("%d\n",tp-);
while(tp>) printf("%d ",stk[tp--]);
puts("");
puts("");
while(tp>) printf("%d ",stk[tp--]);
puts(""); }else if(cnt_odd==){ e.ae(odd[],odd[]); e.ae(odd[],odd[]);
euler(odd[]);
if(tp-<m) fkdown();
while(tp)
{
if(stk[tp]>m) break;
tp--;
}
printf("%d\n",m+-tp);
for(i=m+;i>tp;i--) printf("%d ",stk[i]);
puts("");
tp--; printf("%d\n",tp);
while(tp) printf("%d ",stk[tp--]);
puts(""); }else fkdown();
}else{
int esum=; cnt_odd=; esum=;
for(i=;i<=n;i++)
{
if(!vis[i] || vis[i]==) continue;
if((inc[i]&)) odd[++cnt_odd]=i;
esum+=inc[i];
}
if(cnt_odd> || cnt_odd&) fkdown(); cnt_odd=; esum=;
for(i=;i<=n;i++)
{
if(!vis[i] || vis[i]==) continue;
if((inc[i]&)) odd[++cnt_odd]=i;
esum+=inc[i];
}
if(cnt_odd> || cnt_odd&) fkdown();
esum>>=;
if(!cnt_odd) solve0(,esum);
else if(cnt_odd==) solve2(,esum);
else fkdown(); cnt_odd=; esum=;
for(i=;i<=n;i++)
{
if(!vis[i] || vis[i]==) continue;
if((inc[i]&)) odd[++cnt_odd]=i;
esum+=inc[i];
}
esum>>=;
if(!cnt_odd) solve0(,esum);
else if(cnt_odd==) solve2(,esum);
else fkdown();
}
return ;
}
CF36E Two Paths (欧拉回路+构造)的更多相关文章
- D. Bear and Two Paths(贪心构造)
D. Bear and Two Paths time limit per test 2 seconds memory limit per test 256 megabytes input standa ...
- hdu 4850 字符串构造---欧拉回路构造序列 递归+非递归实现
http://acm.hdu.edu.cn/showproblem.php? pid=4850 题意:构造长度为n的字符序列.使得>=4的子串仅仅出现一次 事实上最长仅仅能构造出来26^4+4- ...
- BZOJ3724PA2014Final Krolestwo——欧拉回路+构造
题目描述 你有一个无向连通图,边的总数为偶数.设图中有k个奇点(度数为奇数的点),你需要把它们配成k/2个点对(显然k被2整除).对于每个点对(u,v),你需要用一条长度为偶数(假设每条边长度为1)的 ...
- BZOJ3724 PA2014Final Krolestwo(欧拉回路+构造)
如果没有长度为偶数的限制,新建一个点向所有奇点连边,跑欧拉回路即可,显然此时一定存在欧拉回路,因为所有点度数都为偶数. 考虑长度为偶数的限制,将每个点拆成两个点放进一个二分图里,那么每条原图中的边在二 ...
- CF1005F Berland and the Shortest Paths (树上构造最短路树)
题目大意:给你一个边权为$1$的无向图,构造出所有$1$为根的最短路树并输出 性质:单源最短路树上每个点到根的路径 ,一定是这个点到根的最短路之一 边权为$1$,$bfs$出单源最短路,然后构建最短路 ...
- 转--python 黑魔法2
Python 高效编程小技巧 个人博客:临风|刀背藏身 Python 一直被我拿来写算法题,小程序,因为他使用起来太方便了,各种niubi闪闪的技能点也在写算法的过程中逐渐被挖掘到,感谢万能的谷哥度娘 ...
- NOI前训练日记
向别人学习一波,记点流水帐.17.5.29开坑. 5.29 早晨看了道据说是树状数组优化DP的题(hdu5542),然后脑补了一个复杂度500^3的meet in the middle.然后死T... ...
- IOI 2020 集训队作业胡扯
首先安慰自己:做的没集训队快很正常-- 很正常-- 做不完也很正常-- 很正常-- 全都不会做也很正常-- 很正常-- 表格 试题一 完成情况 试题二 完成情况 试题三 完成情况 cf549E cf6 ...
- 使用Java8 Files类读写文件
Java8 Files类的newBufferedReader()和newBufferedWriter()方法 这两个方法接受Path类型的参数.Path 类是Java8 NIO中的接口.可以由Path ...
随机推荐
- 异步POST请求解析JSON
异步POST请求解析JSON 一.创建URL NSURL *url = [NSURL URLWithString:@"http://localhost:8080/MJServer/order ...
- 第三章、Tiny4412 U-BOOT移植三 时钟设置【转】
本文转自:http://blog.csdn.net/eshing/article/details/37521789 这一章说明配置时钟频率基本原理 OK,接着说,这次先讲讲CPU的系统时钟.U-BOO ...
- tiny4412 裸机程序 五、控制icache【转】
本文转载自:http://blog.csdn.net/eshing/article/details/37115411 版权声明:本文为博主原创文章,未经博主允许不得转载. 目录(?)[+] 一 ...
- cas4.2的安装
cas4.2使用的是gradle来构建项目的,项目代码在https://github.com/Jasig/cas下载. 然后之后进入项目的根目录,然后执行gradle来编译项目,如下: gradle ...
- P3178 [HAOI2015]树上操作 树链剖分
这个题就是一道树链剖分的裸题,但是需要有一个魔性操作___编号数组需要开longlong!!!震惊!真的神奇. 题干: 题目描述 有一棵点数为 N 的树,以点 为根,且树点有边权.然后有 M 个操作, ...
- java线程异常处理方法
工作中常发现有些程序发生异常但却没有错误日志,原因就是一些开发线程异常处理错误,导致程序报错但异常信息打印到堆栈上,不好在生产环境中定位问题. 在java多线程程序中,所有线程都不允许抛出未捕获的ch ...
- oracle查询时间段
select count(*) tt from crm_cisco_call_detailwhere DateTime between to_date('2016-4-5 00:00:00','yyy ...
- Django day29 视图,路由控制,响应器
一:视图 1.视图的几种方式: (1) 第一种 from rest_framework.mixins import ListModelMixin, CreateModelMixin class Pub ...
- 【BZOJ3205_洛谷3638】[APIO2013]机器人(动态规划)
题目: 洛谷3638 分析: 卡了一天的神题--(OrzJumpmelon) 首先预处理出从点\(p\)向\(d\)方向出发最终能到达的点\(nxt[p][d]\).这个可以直接记忆化搜索解决.如果出 ...
- 【BZOJ1939】[Croatian2010] Zuma(动态规划)
题目: BZOJ1939(权限题) 分析: 这题很容易看出是DP,但是状态和转移都不是很好想-- 用\(dp[l][r][c]\)表示在\(l\)前面已经新加了\(c\)个和\(l\)一样的弹子时,使 ...