点双连通分量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条边,加一条边,求割边最少.(有重边) 分析:先求双连通分量,缩点形成一个生成树,然后求这个的直径,割边-直径即是答案 因为有的图上可能有重边,这样不好处理.我们记录每条边的标号( ...
- 双连通分量(点-双连通分量&边-双连通分量)
概念: 双连通分量有点双连通分量和边双连通分量两种.若一个无向图中的去掉任意一个节点(一条边)都不会改变此图的连通性,即不存在割点(桥),则称作点(边)双连通图. 一个无向图中的每一个极大点(边)双连 ...
随机推荐
- opencv-2-VS2017与QT显示图像
opencv-2-VS2017与QT显示图像 opencvqtVSC++ 目的 使用 VS 构建第一个 opencv 程序 使用 QT 构建 第一个 opencv 程序 VS 导入 QT 程序 开始 ...
- oracle查询当前系统时间前10天的数据
select * from eo_c_order t where t.create_time>systimestamp-interval'1'day; 转载于:https://www.cnblo ...
- IIS6服务器的请求流程(图文&源码)
1.IIS 7开发与管理完全参考手册 http://book.51cto.com/art/200908/146040.htm 2.Web服务IIS 6 https://technet.micro ...
- CF1335E Three Blocks Palindrome
就是我这个菜鸡,赛时写出了 E2 的做法,但是算错复杂度,导致以为自己的做法只能AC E1,就没交到 E2 上,然后赛后秒A..... 题意 定义一种字串为形如:\([\underbrace{a, a ...
- 10 微信小程序路由跳转
一.四种跳转方式 API路由详解 除了tabBar这种底部跳转的方法,我们还有路由跳转,以下四种方式: 1. wx.switchTab() :跳转到 tabBar 页面,并关闭其他所有非 tabBar ...
- <学习笔记之 JQuery>
1. mouseenter 当鼠标指针进入(穿过)元素时,触发事件 var is_enter_help = false; $("#help-div").mouseenter(f ...
- 2-MyBatisPlus教程(HelloWorld)
1,准备数据 DROP TABLE IF EXISTS user; CREATE TABLE user ( id ) NOT NULL COMMENT '主键ID', name ) NULL DEFA ...
- 2020牛客寒假算法基础集训营2 J题可以回顾回顾
2020牛客寒假算法基础集训营2 A.做游戏 这是个签到题. #include <cstdio> #include <cstdlib> #include <cstring ...
- python学习之组成字符串的两种方式
第一种就是加法,比如 a ='张三' b = '李四' 那么print c =a+b 例如之前提到的 或者数值转换成字符串的 num = 100 str(num) 其他参照表格中的转换即可 2.组成 ...
- 王颖奇 20171010129《面向对象程序设计(java)》第十五周学习总结
实验十五 GUI编程练习与应用程序部署 实验时间 2018-12-6 学习总结: 理论部分: ◼ JAR文件◼ 应用程序首选项存储◼ Java Web Start JAR文件: 1.Java程序的打 ...