点双连通分量F. Simple Cycles Edges
2 seconds
256 megabytes
standard input
standard output
You are given an undirected graph, consisting of nn vertices and mm edges. The graph does not necessarily connected. Guaranteed, that the graph does not contain multiple edges (more than one edges between a pair of vertices) or loops (edges from a vertex to itself).
A cycle in a graph is called a simple, if it contains each own vertex exactly once. So simple cycle doesn't allow to visit a vertex more than once in a cycle.
Determine the edges, which belong to exactly on one simple cycle.
The first line contain two integers nn and mm (1≤n≤100000(1≤n≤100000, 0≤m≤min(n⋅(n−1)/2,100000))0≤m≤min(n⋅(n−1)/2,100000)) — the number of vertices and the number of edges.
Each of the following mm lines contain two integers uu and vv (1≤u,v≤n1≤u,v≤n, u≠vu≠v) — the description of the edges.
In the first line print the number of edges, which belong to exactly one simple cycle.
In the second line print the indices of edges, which belong to exactly one simple cycle, in increasing order. The edges are numbered from one in the same order as they are given in the input.
题意:问你给的m条边里面有几条是只属于一个简单环的。
可以求点连通分量,如果点连通分量里面点的数目==边的数目即可。
至于为什么不能用边连通分量,是因为边双连通不能处理一个点既是一个环的组成部分又是另外一个环的组成部分
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=;
int n,m,x,y,low[N],dfn[N],cnt;
int q[N],l,H[N],to[N<<],nxt[N<<],tot=;
int bl[N],scnt;
bool vis[N<<];
int a[N],A[N],ans;
void add(int x,int y){
to[++tot]=y;nxt[tot]=H[x];H[x]=tot;
}
void dfs(int x,int y){
dfn[x]=low[x]=++cnt;
for(int i=H[x];i;i=nxt[i]){
if(to[i]==y||vis[i]) continue;
vis[i]=vis[i^]=;
q[l++]=i;
int v=to[i];
if(!dfn[v]){
dfs(v,x);
low[x]=min(low[x],low[v]);
if(dfn[x]<=low[v]) {
int t,num=,bnum=;
++scnt;
do{
t=q[--l];
if(bl[to[t]]!=scnt) bl[to[t]]=scnt,++num;
if(bl[to[t^]]!=scnt) bl[to[t^]]=scnt,++num;
a[++bnum]=t;
}while(t!=i);
if(num==bnum) for(int i=;i<=bnum;++i) A[++ans]=a[i];
}
}
else low[x]=min(low[x],dfn[v]);
}
}
int main(){
scanf("%d%d",&n,&m);
for(int i=;i<=m;++i) {
scanf("%d%d",&x,&y);
add(x,y);
add(y,x);
}
for(int i=;i<=n;++i) if(!dfn[i]) dfs(i,);
sort(A+,A+ans+);
printf("%d\n",ans);
for(int i=;i<=ans;++i) printf("%d ",A[i]>>);
}
边连通是不可行的,模板备用.
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=1e5+;
int dfn[N],low[N],H[N],nxt[N<<],to[N<<];
int n,m,x,y,cnt,tot=;
bool ib[N],is[N];
void add(int x,int y){
to[++tot]=y;nxt[tot]=H[x];H[x]=tot;
}
void dfs(int u,int fa){
low[u]=dfn[u]=++cnt;
int chi=;
for(int i=H[u];i;i=nxt[i]){
int v=to[i];
if(v==fa) continue;
if(!dfn[v]) {
++chi;
dfs(v,u);
low[u]=min(low[u],low[v]);
if(low[v]>dfn[u]) ib[i]=ib[i^]=;
if(low[v]>=dfn[u]) is[u]=;
}
else low[u]=min(low[u],dfn[v]);
}
if(chi==&&fa==-) is[u]=;
}
int num,bnum,a[N],A[N],ans;
void dfs2(int u,int fa){
++num;for(int i=H[u];i;i=nxt[i]) {
int v=to[i];
if(ib[i]||ib[i^]||v==fa) continue;
ib[i]=ib[i^]=;
a[++bnum]=i>>;
if(!dfn[v]) dfn[v]=,dfs2(v,u);
}
}
int main(){
scanf("%d%d",&n,&m);
for(int i=;i<=m;++i) {
scanf("%d%d",&x,&y);
add(x,y);
add(y,x);
}
for(int i=;i<=n;++i) if(!dfn[i]) dfs(i,-);
for(int i=;i<=n;++i) dfn[i]=;
for(int i=;i<=n;++i) if(!dfn[i]) {
num=bnum=;
dfn[i]=;
dfs2(i,-);
if(num==bnum) for(int j=;j<=num;++j) A[++ans]=a[j];
}
printf("%d\n",ans);
sort(A+,A+ans+);
for(int i=;i<=ans;++i) printf("%d ",A[i]);
}
点双连通分量F. Simple Cycles Edges的更多相关文章
- Educational Codeforces Round 42 (Rated for Div. 2)F - Simple Cycles Edges
http://codeforces.com/contest/962/problem/F 求没有被两个及以上的简单环包含的边 解法:双联通求割顶,在bcc中看这是不是一个简单环,是的话把整个bcc的环加 ...
- codeforces 962 F Simple Cycles Edges
求简单环,即求点=边数的点双分量,加上判断点和边的模板即可 (简单环模板,区分与点双缩点) ; ], edgecnt, dfn[maxm], low[maxm], bcc_cnt, bccnum[ma ...
- CF962F Simple Cycles Edges
CF962F Simple Cycles Edges 给定一个连通无向图,求有多少条边仅被包含在一个简单环内并输出 \(n,\ m\leq10^5\) tarjan 首先,一个连通块是一个环,当且仅当 ...
- Codeforces962F Simple Cycles Edges 【双连通分量】【dfs树】
题目大意: 给出一个无向图,问有哪些边只属于一个简单环. 题目分析: 如果这道题我们掌握了点双连通分量,那么结论会很显然,找到每个点双,如果一个n个点的点双正好由n条边构成,那么这些边都是可以的. 这 ...
- Simple Cycles Edges CodeForces - 962F(点双连通分量)
题意: 求出简单环的所有边,简单环即为边在一个环内 解析: 求出点双连通分量,如果一个连通分量的点数和边数相等,则为一个简单环 点双连通分量 任意两个点都至少存在两条点不重复的路径 即任意两条边都 ...
- codeforces 962F.simple cycle(tarjan/点双连通分量)
题目连接:http://codeforces.com/contest/962/problem/F 题目大意是定义一个simple cycle为从一个节点开始绕环走一遍能经过simple cycle内任 ...
- HDU 5458 Stability(双连通分量+LCA+并查集+树状数组)(2015 ACM/ICPC Asia Regional Shenyang Online)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5458 Problem Description Given an undirected connecte ...
- hdu-4612-Warm up(边双连通分量--有重边)
题意:有N 个点,M条边,加一条边,求割边最少.(有重边) 分析:先求双连通分量,缩点形成一个生成树,然后求这个的直径,割边-直径即是答案 因为有的图上可能有重边,这样不好处理.我们记录每条边的标号( ...
- 双连通分量(点-双连通分量&边-双连通分量)
概念: 双连通分量有点双连通分量和边双连通分量两种.若一个无向图中的去掉任意一个节点(一条边)都不会改变此图的连通性,即不存在割点(桥),则称作点(边)双连通图. 一个无向图中的每一个极大点(边)双连 ...
随机推荐
- Libra教程之:Libra protocol的逻辑数据模型
文章目录 Libra protocol简介 逻辑数据模型 账本状态 交易 账本历史 Libra protocol简介 Libra区块链本质上是一个加密数据库,这个数据库是通过Libra protoco ...
- mac OS npm 安装/卸载失败 权限问题解决方案
在终端输入 sudo chown -R $USER /usr/local 输入开机密码
- Failed building wheel for cytoolz
2019独角兽企业重金招聘Python工程师标准>>> 当我使用 pip instlal cytoolz 时, 报以下错误: error: Microsoft Visual C++ ...
- Pika源码学习--pika的通信和线程模型
pika的线程模型有官方的wiki介绍https://github.com/Qihoo360/pika/wiki/pika-%E7%BA%BF%E7%A8%8B%E6%A8%A1%E5%9E%8B,这 ...
- 从一条数据说起——InnoDB存储数据结构
本篇博客参考掘金小册--MySQL 是怎样运行的:从根儿上理解 MySQL 先给大家讲一个故事,我刚参加工作,在一个小作坊里面当[码畜](尽管现在也是),有一天老板从我背后走过,说了一句举世震惊的话: ...
- HDU 3038 (向量图解)
题意:\(有n个人坐在zjnu体育馆里面,然后给出m个他们之间的距离, A B X, 代表B的座位比A多X.\) \(然后求出这m个关系之间有多少个错误,所谓错误就是当前这个关系与之前的有冲突\) \ ...
- 002_python的in,while else,格式化输出,逻辑运算符,int与bool转换,编码
数据 1.什么是数据? x=10,10是我们要存储的数据 2.为何数据要分不同的类型 数据是用来表示状态的,不同的状态就应该用不同的类型的数据去表示 3.数据类型 数字 字符串 列表 元组 字典 集合 ...
- 【FreeRTOS学习06】深度解剖中断与任务之间同步的具体使用场景
嵌入式系统中中断是必不可少的一部分: [FreeRTOS实战汇总]小白博主的RTOS学习实战快速进阶之路(持续更新) 文章目录 1 前言 2 中断特点 3 延迟中断处理 3.1 信号量的使用 3.2 ...
- Java中Error和Exception的异同以及运行时异常(Runtime exception)与检查型异常(checked exception)的区别
一:Error和Exception的基本概念: 首先Exception和Error都是继承于Throwable 类,在 Java 中只有 Throwable 类型的实例才可以被抛出(throw)或者捕 ...
- elasticsearch kibana的安装部署与简单使用(一)
1.先说说es 我早两年使用过es5.x的版本,记得当时部署还是很麻烦,因为es是java写的,要先在机器上部署java环境jvm之类的一堆东西,然后才能安装es 但是现在我使用的是目前最新的7.6版 ...