【UOJ 117】欧拉回路
#117. 欧拉回路
有一天一位灵魂画师画了一张图,现在要你找出欧拉回路,即在图中找一个环使得每条边都在环上出现恰好一次。
一共两个子任务:
- 这张图是无向图。(50分)
输入格式
第一行一个整数 t,表示子任务编号。t∈{1,2},如果 t=1则表示处理无向图的情况,如果 t=2 则表示处理有向图的情况。
第二行两个整数 n,m,表示图的结点数和边数。
接下来 m 行中,第 i 行两个整数 vi,ui,表示第 ii 条边(从 11 开始编号)。保证 1≤vi,ui≤n
- 如果 t=1
- 则表示 vi 到 ui 有一条无向边。
- 如果 t=2
- 则表示 vi 到 ui 有一条有向边。
图中可能有重边也可能有自环。
输出格式
如果不可以一笔画,输出一行 “NO”。
否则,输出一行 “YES”,接下来一行输出一组方案。
如果 t=1,输出 m个整数 p1,p2,…,pm。令 e=∣pi∣,那么 e 表示经过的第 i 条边的编号。如果 pi 为正数表示从 ve 走到 ue,否则表示从 ue 走到 ve。
如果 t=2,输出 m 个整数 p1,p2,…,pm。其中 pi 表示经过的第 i条边的编号。
样例一
input
1
3 3
1 2
2 3
1 3output
YES
1 2 -3样例二
input
2
5 6
2 3
2 5
3 4
1 2
4 2
5 1output
YES
4 1 3 5 2 6限制与约定
1≤n≤10^5,0≤m≤2×10^5
时间限制:1s
空间限制:256MB
【分析】
这是欧拉回路的模板题。
主要是这样:
无向图:所有点的度数都为偶数,一定有欧拉回路,从任意一个点开始都可以。
有向图:所有点的入度=出度,一定有欧拉回路,从任意一个点开始都可以。
我们不断走边,边没打过标记的就走,经过一条边就打标记,表示不能走这条边了,然后回溯的时候把路径记录下来,反着输出就可以。
走过的边不仅要打标记(主要是无向图的反向边要标记一下),还要删除,不然即使不再走这条边也会不断询问它而导致TLE,
解决方法是改变边目录的first数组,表示前面访问过的边都不用再继续访问了。
void ffind(int x)
{
vis[x]=1;
for(int i=first[x];i;i=first[x]) if(t[i].p)
{
int y=t[i].y;
t[i].p=t[t[i].o].p=0;
first[x]=t[i].next;
ffind(y);
op[++op[0]]=t[i].id;
}
else first[x]=t[i].next;
}
核心代码如上。
【GDXB当初告诉我这叫套圈算法?
【主要是回溯那里还有删边那里要记得。
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
#include<stack>
using namespace std;
#define Maxm 200010
#define Maxn 100010 struct node
{
int x,y,c,next,o;
int id;
bool p;
}t[*Maxm];
int first[Maxn],len;
int T; void ins(int x,int y,int id)
{
t[++len].x=x;t[len].y=y;t[len].p=;
t[len].id=id;t[len].next=first[x];first[x]=len;
if(T==) t[len].o=len&?len+:len-;
else t[len].o=len;
} int rd[Maxn],cd[Maxn],op[Maxm];
bool nw=,vis[Maxn]; void ffind(int x)
{
vis[x]=;
for(int i=first[x];i;i=first[x]) if(t[i].p)
{
int y=t[i].y;
t[i].p=t[t[i].o].p=;
first[x]=t[i].next;
ffind(y);
op[++op[]]=t[i].id;
}
else first[x]=t[i].next;
} int main()
{
scanf("%d",&T);
int n,m;
scanf("%d%d",&n,&m);
len=;
memset(first,,sizeof(first));
memset(rd,,sizeof(rd));
memset(cd,,sizeof(cd));
for(int i=;i<=m;i++)
{
int x,y;
scanf("%d%d",&x,&y);
rd[y]++;cd[x]++;
ins(x,y,i);
if(T==) ins(y,x,-i);
}
bool ok=;
for(int i=;i<=n;i++) if(T==&&(rd[i]+cd[i])%!=) {ok=;break;}
for(int i=;i<=n;i++) if(T==&&rd[i]!=cd[i]) {ok=;break;}
op[]=;
if(!ok) printf("NO\n");
else
{
for(int i=;i<=n;i++) vis[i]=;
for(int i=;i<=n;i++)
{
ffind(i);
if(op[]!=) break;
}
if(T==&&op[]!=len/) printf("NO\n");
else if(T==&&op[]!=len) printf("NO\n");
else
{
printf("YES\n");
for(int i=op[];i>=;i--)
{
printf("%d ",op[i]);
}
printf("\n");
} }
return ;
}
2017-03-02 21:09:04
【UOJ 117】欧拉回路的更多相关文章
- UOJ#117. 欧拉回路
#117. 欧拉回路 题目描述 有一天一位灵魂画师画了一张图,现在要你找出欧拉回路,即在图中找一个环使得每条边都在环上出现恰好一次. 一共两个子任务: 这张图是无向图.(50分) 这张图是有向图.(5 ...
- 暑假集训2016day3T1 欧拉回路(UOJ #117欧拉回路)(史上最全的欧拉回路纯无向图/有向图解析)
原题……可惜不会……真是一只大蒟蒻…… ———————————————————————————————— 有一天一位灵魂画师画了一张图,现在要你找出欧拉回路,即在图中找一个环使得每条边都在环上出现恰好 ...
- UOJ 117 欧拉回路(套圈法+欧拉回路路径输出+骚操作)
题目链接:http://uoj.ac/problem/117 题目大意: 解题思路:先判断度数: 若G为有向图,欧拉回路的点的出度等于入度. 若G为无向图,欧拉回路的点的度数位偶数. 然后判断连通性, ...
- 「UOJ#117」 欧拉回路
欧拉回路 - 题目 - Universal Online Judge 题意: 给定有向图或无向图,求一条欧拉回路. 题解 心路历程:woc什么傻哔东西->哇真香我的吗!(逃 首先我知道很多人把欧 ...
- 【UOJ#236】[IOI2016]railroad(欧拉回路,最小生成树)
[UOJ#236][IOI2016]railroad(欧拉回路,最小生成树) 题面 UOJ 题解 把速度看成点,给定的路段看成边,那么现在就有了若干边,然后现在要补上若干边,以及一条\([inf,\) ...
- 【UOJ#177】欧拉回路
[UOJ#177]欧拉回路 题面 UOJ 题解 首先图不连通就没啥好搞的了. 对于无向图而言,每个点度数为偶数. 对于有向图而言,每个点入度等于出度. 然后就是一本通上有的做法,直接\(dfs\)一遍 ...
- 【UOJ#389】【UNR#3】白鸽(欧拉回路,费用流)
[UOJ#389][UNR#3]白鸽(欧拉回路,费用流) 题面 UOJ 题解 首先第一问就是判断是否存在一条合法的欧拉回路,这个拿度数和连通性判断一下就行了. 第二问判断转的圈数,显然我们只需要考虑顺 ...
- UOJ117:欧拉回路——题解
http://uoj.ac/problem/117 (作为一道欧拉回路的板子题,他成功的令我学会了欧拉回路) (然而我不会背……) 就两件事: 1.无向图为欧拉图,当且仅当为连通图且所有顶点的度为偶数 ...
- UOJ Round #15 [构造 | 计数 | 异或哈希 kmp]
UOJ Round #15 大部分题目没有AC,我只是水一下部分分的题解... 225[UR #15]奥林匹克五子棋 题意:在n*m的棋盘上构造k子棋的平局 题解: 玩一下发现k=1, k=2无解,然 ...
随机推荐
- Oracle Number类型超长小数位为0问题
碰到了一个非常奇怪的问题,从Excel拷贝出来的数据,位数很长,通过Pl Sql 导出到Oracle后为0了,而且设置查询条件为0时,无法查询出来,条件大于0居然能查询出来,通过to_number也是 ...
- IDEA常见错误
1. inspects a maven model for resolution problems 在添加Maven依赖的时候,报了inspects a maven model for resolut ...
- Windows下Oracle数据库自动备份批处理脚本
expdb命令版本 @echo off REM ########################################################### REM # Windows Se ...
- List基本用法
List最为Collection接口的子接口,当然可以使用Collection接口里的全部方法.而且由于List是有序集合,因此List集合里增加了一些根据索引来操作集合元素的方法: public c ...
- 一个带重试次数的curl 函数
<?php/** * [curl 带重试次数] * @param [type] $url [访问的url] * @param [type] $post [$POST参数] * @param in ...
- 详述Linux配置静态IP、设置DNS和主机名(一)
Linux配置静态IP.设置DNS和主机名首先要找到配置文件,这是在Linux系统下进行工作的必须知道工作方式.后面一步步的跟着这个范例来进行配置相信你最终也会完成Linux配置静态IP.设置DNS和 ...
- struct中长度为0的数组用途与原理
前言 在标准C和C++中,长度为0的数组是被禁止使用的.不过在GNUC中,存在一个非常奇怪的用法,那就是长度为0的数组,比如Array[0]; 很多人可能觉得不可思议,长度为0的数组是没有什么意义的, ...
- Codeforces 375D - Tree and Queries(dfs序+莫队)
题目链接:http://codeforces.com/contest/351/problem/D 题目大意:n个数,col[i]对应第i个数的颜色,并给你他们之间的树形关系(以1为根),有m次询问,每 ...
- csu 1550(字符串处理思路题)
1550: Simple String Time Limit: 1 Sec Memory Limit: 256 MBSubmit: 481 Solved: 211[Submit][Status][ ...
- linux中使用vim编译C++程序
Vi三种模式详解 命令行模式 (command mode/一般模式) 任何时候,不管用户处于何种模式,只要按一下“ESC”键,即可使Vi进入命令行模式:我们在shell环境(提示符为$)下输入启动Vi ...