首先研究环上性质,发现如果状态不变的边就不需要动了,每次改的环上边肯定都是起末状态不同的边且仅改一次,因为如果有一条边在多个环上,相当于没有改,无视这条边之后,这几个环显然可以并成一个大环。所以,我们只关注起末状态不同的边。

然后,这些边形成一张图。对于每个连通块,如果有解的话,应当是一堆边不相交的简单环通过点互相连接的。这样一张图等价于一个欧拉回路,所以只要判每个连通块是不是欧拉回路(偶数度)即可。

然后是求解,目标就是把每个连通块所有的简单环都拎出来。回顾上述欧拉回路判断,实际上正是因为若干简单环构成的图可以一笔画。。所以仿照一笔画过程(也就是栈中记录的访问点顺序),再开一个栈,不断压栈,当遇到一个先前已经压到栈的点的时候说明形成了一个简单环,一直弹栈直到先前点为止,这时弹出元素就构成了一个环。。这样所有环就出来了。

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#define mst(x) memset(x,0,sizeof x)
#define dbg(x) cerr << #x << " = " << x <<endl
#define dbg2(x,y) cerr<< #x <<" = "<< x <<" "<< #y <<" = "<< y <<endl
using namespace std;
typedef long long ll;
typedef double db;
typedef pair<int,int> pii;
template<typename T>inline T _min(T A,T B){return A<B?A:B;}
template<typename T>inline T _max(T A,T B){return A>B?A:B;}
template<typename T>inline char MIN(T&A,T B){return A>B?(A=B,):;}
template<typename T>inline char MAX(T&A,T B){return A<B?(A=B,):;}
template<typename T>inline void _swap(T&A,T&B){A^=B^=A^=B;}
template<typename T>inline T read(T&x){
x=;int f=;char c;while(!isdigit(c=getchar()))if(c=='-')f=;
while(isdigit(c))x=x*+(c&),c=getchar();return f?x=-x:x;
}
const int N=1e5+,M=1e6+;
struct thxorz{
int head[N],to[M<<],nxt[M<<],tot;
thxorz(){tot=;}
inline void add(int x,int y){
to[++tot]=y,nxt[tot]=head[x],head[x]=tot;
to[++tot]=x,nxt[tot]=head[y],head[y]=tot;
}
}G;
int deg[N],stk[M],vis[M<<],bin[M],bcnt,top,st[N],tp,instk[N];
int n,m,cnt;
#define y G.to[j]
void dfs(int x){//dbg(x);
for(register int&j=G.head[x];j;j=G.nxt[j])if(!vis[j])vis[j]=vis[j^]=,bin[++bcnt]=j,dfs(y);
stk[++top]=x;
}
#undef y
vector<int> ans[M];
int main(){//freopen("test.in","r",stdin);//freopen("test.ans","w",stdout);
read(n),read(m);
for(register int i=,x,y,z,w;i<=m;++i){
read(x),read(y),read(z),read(w);
if(z^w)G.add(x,y),++deg[x],++deg[y];
}
for(register int i=;i<=n;++i)if(deg[i]&){puts("NIE");return ;}
for(register int i=;i<=n;++i)if(G.head[i]){
dfs(i);tp=;//dbg(i);
while(bcnt)vis[bin[bcnt]]=vis[bin[bcnt]^]=,--bcnt;
while(top){
int x=stk[top--];//dbg(x);
if(!instk[x])instk[x]=,st[++tp]=x;
else{
ans[++cnt].push_back(x);
do instk[st[tp]]=,ans[cnt].push_back(st[tp--]);while(st[tp]^x);
ans[cnt].push_back(x);
}
}
}
printf("%d\n",cnt);
for(register int i=;i<=cnt;++i,puts("")){
printf("%d ",ans[i].size()-);
for(register int j=;j<ans[i].size();++j)printf("%d ",ans[i][j]);
}
return ;
}

总结:这题启示我们在有关简单环的问题中,除了点双、边双等等转化策略以外,在涉及环的方面也可以采用欧拉路来考虑。总之,解决环相关的问题大概就是点双、边双、欧拉路以及栈的思想、dfs以及二分图染色等方法。

BZOJ2278 [Poi2011]Garbage[欧拉回路求环]的更多相关文章

  1. [POI2011]Garbage 欧拉回路

    [POI2011]Garbage 链接 https://www.lydsy.com/JudgeOnline/problem.php?id=2278 https://loj.ac/problem/216 ...

  2. BZOJ2278 : [Poi2011]Garbage

    如果两个环相交,那么相交的部分相当于没走. 因此一定存在一种方案,使得里面的环都不相交. 把不需要改变状态的边都去掉,剩下的图若存在奇点则无解. 否则,每找到一个环就将环上的边都删掉,时间复杂度$O( ...

  3. Codeforces Round #346 (Div. 2) E - New Reform 无相图求环

    题目链接: 题目 E. New Reform time limit per test 1 second memory limit per test 256 megabytes inputstandar ...

  4. POJ 1860 Currency Exchange / ZOJ 1544 Currency Exchange (最短路径相关,spfa求环)

    POJ 1860 Currency Exchange / ZOJ 1544 Currency Exchange (最短路径相关,spfa求环) Description Several currency ...

  5. codevs4511信息传递(Tarjan求环)

    题目描述 有n个同学(编号为1到n)正在玩一个信息传递的游戏.在游戏里每人都有一个固定的信息传递对象,其中,编号为i的同学的信息传递对象是编号为Ti同学. 游戏开始时,每人都只知道自己的生日.之后每一 ...

  6. poj 2240 Bellman-Flod 求环

    http://poj.org/problem?id=2240 深刻体现了自己代码能力有问题外加改模板能力有问题.外加Debug有问题.以后做到: 1.算法原理能够轻易弄出来. 2.代码模板自己收集各种 ...

  7. AC日记——传话 codevs 1506 (tarjan求环)

    1506 传话  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 白银 Silver 题解       题目描述 Description 一个朋友网络,如果a认识b,那么如果a第 ...

  8. HDU - 6041:I Curse Myself(Tarjan求环&K路归并)

    There is a connected undirected graph with weights on its edges. It is guaranteed that each edge app ...

  9. 洛谷P2444 [POI2000]病毒(AC自动机,DFS求环)

    洛谷题目传送门 AC自动机入门--yyb巨佬的博客 AC自动机入手经典好题(虽然年代久远) 有了fail指针,trie树就不是原来的树型结构了,我们可以把它叫做trie图,由父节点向子节点连的边和fa ...

随机推荐

  1. 最新 汇量科技java校招面经 (含整理过的面试题大全)

    从6月到10月,经过4个月努力和坚持,自己有幸拿到了网易雷火.京东.去哪儿. 汇量科技等10家互联网公司的校招Offer,因为某些自身原因最终选择了 汇量科技.6.7月主要是做系统复习.项目复盘.Le ...

  2. 第35课.函数对象分析("()"重载)

    1.编写一个函数 a.函数可以获得斐波那契数列 b.每调一次返回一个值 c.函数可以根据需要重复使用 2.函数数对象 a.使用具体的类对象取代函数 b.改类的对象具备函数调用的行为 c.构造函数指具体 ...

  3. 2019icpc南昌网络赛

    B. Fire-Fighting Hero (dijstra优先队列+bfs) 题意:刚开始看错题了,以为是k次dijkstra,但是wa了,后来队友指正后发现挺水的.求S到其它点的最短路的最大值an ...

  4. libtool

    [从网上摘录的,忘了从哪摘的了]   libtool常见于autoconf/automake,单独用的例子很少,所以我想仔细研究一下,为将来兄弟们看起来方便. 一.libtool的作用offer a ...

  5. [转]Mybatis之TypeHandler使用教程

    Mybatis之TypeHandler使用教程 https://blog.csdn.net/jokemqc/article/details/81326109 深入浅出Mybatis系列(五)---Ty ...

  6. Two progressions(CodeForces-125D)【鸽巢原理】

    题意:将一列数划分为两个等差数列. 思路:首先,我要吹爆鸽巢原理!!!真的很强大的东西!!! 加入能完成题设操作,则前三个数中,必有至少两个数在同一序列,枚举三种情况(a1 a2,a2 a3,a1 a ...

  7. 解决python语言在cmd下中文乱码的问题

    解决python语言在cmd下中文乱码的问题: a = "再见!"print (a.decode('utf-8').encode('gbk')) #解决在cmd下中文乱码的问题

  8. 序列化,os,sys,hashlib,collections

    序列化,os,sys,hashlib,collections 1.序列化 什么是序列化?序列化的本质就是将一种数据结构(如字典,列表)等转换成一个特殊的序列(字符串或者bytes)的过程就叫做序列化. ...

  9. Python简介以及入门

    一. Python简介 1. Python的诞生 Python的创始人是吉多·范罗苏姆(Guido van Rossum),荷兰人.1989年的圣诞节期间,吉多·范罗苏姆(中文名字:龟叔)为了在阿姆斯 ...

  10. S03_CH03_AXI_DMA_OV7725摄像头采集系统

    S03_CH03_AXI_DMA_OV7725摄像头采集系统 3.1概述 本课程讲解如何搭建基于DMA的图形系统,方案原理如下. 摄像头采样图像数据后通过DMA送入到DDR,在PS部分产生DMA接收中 ...