有向图寻找(一个)奇环 -- find an oddcycle in directed graph
/// the original blog is http://www.cnblogs.com/tmzbot/p/5579020.html , automatic crawling without link to original blog is unallowed.
判定 + 寻找一组解
(感觉这个东西挺有意思的记录一下..)
/// the original blog is http://www.cnblogs.com/tmzbot/p/5579020.html , automatic crawling without link to original blog is unallowed.
Algorithm.A
暴力吧.. 暴力枚举每个环判断一下.. (不知道什么复杂度..反正大概是指数级别的,说错了别打我,怕疼)
/// the original blog is http://www.cnblogs.com/tmzbot/p/5579020.html , automatic crawling without link to original blog is unallowed.
Algorithm.B
先把强联通分量搞出来. \(O(n+m)\)
然后考虑对点dfs二染色并同时维护传递闭包(这里传递闭包的定义是\(v\in \mathtt{closure}(u)\)当且仅当dfn[v]<dfn[u]且u可以访问到v),枚举出边(u,v)的时候若有一边是两端同色(这条边一定是返祖边或横向边,理由dfn[u]>dfn[v]),如果是返祖边(inStack[v])那就不用做了,如果是横向边考虑v的传递闭包中的u祖先, 判断是不是奇环. 总复杂度\(O(n^2)\). 用线段树启发式合并的技巧我们就能得到一个优秀又难写的\(O(n^2\log{n})\)算法.
/// the original blog is http://www.cnblogs.com/tmzbot/p/5579020.html , automatic crawling without link to original blog is unallowed.
Algorithm.C
我们考虑一个出发点不太一样的做法.
我们拆点, 将一个点u分为两个点W(u)和B(u).原图需要加入边(u,v)的时候我们加入W(u)->B(v), B(u)->W(v).
那么考虑原图中存在一个奇环当且仅当存在u使得W(u)可以达到B(u)或B(u)可以达到W(u),把这段路径搞下来变成原来节点就是要找的环了.
那么我们对于每个点W(u)和B(u)都dfs一下看看能不能到达就好了. 因为对称性所以B(u)上是无需dfs的. \(O(n^2)\)
/// the original blog is http://www.cnblogs.com/tmzbot/p/5579020.html , automatic crawling without link to original blog is unallowed.
Algorithm.D
然而好像无需这么干..
若一个有奇环a,b,c,...,x,y(不要管它字母是怎么写的,其中元素有多少个,反正是奇数个), 不失一般性我们认为a是最先访问到的节点,而此时b,c,...,x,y都没有被访问过, 显然需要存在W(a)->B(b)->W(c)->...->W(y)->B(a)
在这条路径上除了a以外颜色都是固定的.我们假设没有按照这条路径先走而是走了例如W(a)->B(X)->W(y)的路径, 显然奇偶性是没有改变的, 那么要是原来能找到奇环那么先在也能走到奇环, 而只要W(a)能访问到W(y)那么一定从W(a)出发会走到W(y), 那肯定能发现一个奇环.
如果存在一个奇环显然有一个节点是最先访问的,而此时所有其它奇环上的顶点都没被访问过.
那么只要有一个奇数环一定能找到.
复杂度是\(O(n+m)\)的.
一道裸题的代码
/// the original blog is http://www.cnblogs.com/tmzbot/p/5579020.html , automatic crawling without link to original blog is unallowed.
#include <cstdio>
#include <cstring>
#include <algorithm>
const int maxn = 200010;
const int maxm = 2000010;
namespace Graph{
struct ed{
int t;
ed* n;
}*h[maxn],Al[maxm],*p=Al;
inline void ade(int f,int t){ *p=(ed){t,h[f]}; h[f]=p++; }
bool vis[maxn], inq[maxn];
int stk[maxn],stt;
int cycle[maxn], cycleLen;
void dfs(int n){
vis[n]=inq[n]=1;
stk[stt++]=n;
for(ed*i=h[n];i;i=i->n){
int vx;
if(inq[vx=(i->t^1)]){
while(stk[--stt]!=vx)
cycle[cycleLen++]=stk[stt];
cycle[cycleLen++]=vx;
}else if(!vis[i->t]) dfs(i->t);
if(cycleLen) return;
} --stt;
inq[n]=0;
}
inline void init(int n){
for(int i=2,_=n*2+1;i<=_;++i){
inq[i]=vis[i]=0;
h[i]=NULL;
} p=Al, cycleLen=0, stt=0;
}
inline void work(){
int n,m; scanf("%d%d",&n,&m);
init(n);
for(int i=1,a,b;i<=m;++i){
scanf("%d%d",&a,&b);
ade(a<<1,b<<1|1);
ade(a<<1|1,b<<1);
}
for(int i=2,_=2*n+1;i<=_;++i) if(!vis[i]){
dfs(i);
if(cycleLen) break;
}
if(cycleLen){
printf("1\n%d\n",cycleLen);
for(int i=cycleLen-1;~i;--i) printf("%d\n",cycle[i]>>1);
}else
printf("-1\n");
}
} using namespace Graph;
int main(){
int t; scanf("%d",&t);
while(t--) work();
return 0;
}
有向图寻找(一个)奇环 -- find an oddcycle in directed graph的更多相关文章
- hdu 3478(判断奇环)
题意:给你一个无向图,问你有没有可能存在一个奇环连接所有的节点. 分析:好久没写博客了,这个好习惯还是要继续保持的!这道题通过转化之后就是问你有没有存在一个奇环连接所有的节点,这里用到的方法是染色法, ...
- cf19E. Fairy(奇环 二分图染色)
题意 题目链接 Sol 非常有思维含量的一道题,队爷的论文里介绍了一种\(N \sqrt{N}\)的暴力然鹅看不懂.. 看了一下clj的\(O(nlogn)\)的题解,又翻了翻题交记录,发现\(O(n ...
- Catch---hdu3478(染色法判断是否含有奇环)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3478 题意:有n个路口,m条街,一小偷某一时刻从路口 s 开始逃跑,下一时刻都跑沿着街跑到另一路口,问 ...
- BZOJ1040: [ZJOI2008]骑士(奇环树,DP)
题目: 1040: [ZJOI2008]骑士 解析: 假设骑士\(u\)讨厌骑士\(v\),我们在\(u\),\(v\)之间连一条边,这样我们就得到了一个奇环树(奇环森林),既然是一颗奇环树,我们就先 ...
- HDU-5215 Cycle 无向图判奇环偶环
题意:给一个无向图,判断这个图是否存在奇环和偶环. 解法:网上有一种只用dfs就能做的解法,但是我不太理解. 这里用的是比较复杂的.首先奇环很简单可以用二分图染色判断.问题是偶环怎么判断?这里我们想, ...
- [转载]HDU 3478 判断奇环
题意:给定n个点,m条边的无向图(没有重边和子环).从给定点出发,每个时间走到相邻的点,可以走重复的边,相邻时间不能停留在同一点,判断是否存在某个时间停留在任意的n个点. 分析: (1)首先,和出发点 ...
- Codeforces Round #311 (Div. 2) D. Vitaly and Cycle 奇环
题目链接: 点这里 题目 D. Vitaly and Cycle time limit per test1 second memory limit per test256 megabytes inpu ...
- poj2942 求v-DCC,二分图判奇环,补图
/* 给定一张无向图,求有多少点不被任何奇环包含 推论1:如果两个点属于两个不同的v-DCC,则他们不可能在同一个奇环内 推论2:某个v-DCC中有奇环,则这个v-DCC中所有点必定被属于某个奇环 只 ...
- qbxt的题:找一个三元环
有向图中找一个三元环 题意: 考虑 N 个人玩一个游戏, 任意两个人之间进行一场游戏 (共 N*(N-1)/2 场),且每场一定能分出胜负.现在,你需要在其中找到三个人构成的这样的局面:A战胜B,B战 ...
随机推荐
- 在线考试系统(Online Exam System)--ASP.NET
用户设计 -|学生 -|老师 -|管理员 学生结构设计 -|个人信息管理 -|修改个人信息 -|修改登录密码 -|选课中心 -|显示所有老师所开课的信息可进行选课 -|显示自己已选课程 -|在线考试 ...
- Quartz.NET总结(三)Quartz 配置
前两篇文章,已经介绍了Quartz.NET的使用和Cron表达式表达式的写法,今天说一说Quartz的配置,Quartz相关的配置有三个quartz.config.quartz_jobs.xml.lo ...
- String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+pat----------<base>元素有关
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request. ...
- OC-SEL
SEL SEL对应方法的地址 _cmd代表当前方法 1. 方法的存储位置 每个类的方法列表都存储在类对象中 每个方法都有一个与之对应的SEL类型的对象 根据一个SEL对象就可以找到方法的地址,进而调 ...
- canvas代替img渲染图片
移动端用canvas代替img渲染图片,可以提高性能 var oImg = new Image(); oImg.src = url; oImg.onload = function(){ var cvs ...
- 为IIS Express添加MIME映射
VS2013自带IIS Express,无法发布JSON文件,需添加MIME映射. 没有图形界面,只能命令行. 进入C:\Program Files(x86)\IIS Express文件夹,输入:ap ...
- jquery 清除动画队列不疑惑
$(this).siblings().stop().fadeTo(200, 0.3); jquery动画存在一个队列, 会把事件产生的动画 放在一个队列中,当来不及执行这些事件队列的时候,会在事件结束 ...
- Supervisor 安装与配置
Supervisor是一个进程监控程序. 满足的需求是:我现在有一个进程需要每时每刻不断的跑,但是这个进程又有可能由于各种原因有可能中断.当进程中断的时候我希望能自动重新启动它,此时,我就需要使用到了 ...
- Linux下查看文件内容的命令
查看文件内容的命令: cat 由第一行开始显示内容,并将所有内容输出 tac 从最后一行倒序显示内容,并将所有内容输出 more 根据窗口大小,一页一页的现实文件内容 less ...
- 条件查询N多的情况下,回显解决方法。
条件查询每个web程序员一定都写过,关于条件回显值页面的思路很简单,将页面的值传到后台,放置request作用域,然后回显至页面. 如果几个条件还好些,如果是下面这种情况呢? 如果条件像以上情况N多情 ...