题目大意:

  给出一个无向图,问有哪些边只属于一个简单环。

题目分析:

  如果这道题我们掌握了点双连通分量,那么结论会很显然,找到每个点双,如果一个n个点的点双正好由n条边构成,那么这些边都是可以的。

  这样想显得很没有技术含量,使用一类通用的做法做一些有特点的题目总是不那么锻炼人的思维,但在算法竞赛中我仍然推荐点双的做法。

  这题很有特点,我们尝试不用点双解决它。

  首先,考虑一个简单环,它不由几个简单环组合并删去某些边组合而成。它的dfs树的形状将会是这样的:

  

  其中箭头标注的是返祖边。

  一个简单环中的所有边被选,当且仅当它唯一的一条返祖边所包括的点不被其它返祖边所覆盖任何一段,但是这一段并不包含仅包含一个点的情况。

  所以我们可以考虑类似运输计划那样的差分。然后前缀和维护经过的返祖边大于2的边数,这样对每条返祖边判断是O(1)的。所以时间复杂度O(n+m+sort(m))。

代码:

  

 #include<bits/stdc++.h>
using namespace std; const int maxn = ; #define mp make_pair int n,m; struct edge{int from,to;}e[maxn];
vector<pair<int,int> > g[maxn];
int dfn[maxn],f[maxn],dd[maxn],cl,pt[maxn];
int chs[maxn],lnk[maxn]; void read(){
scanf("%d%d",&n,&m);
for(int i=;i<=m;i++){
scanf("%d%d",&e[i].from,&e[i].to);
g[e[i].from].push_back(mp(e[i].to,i));
g[e[i].to].push_back(mp(e[i].from,i));
}
} vector<int> ans;
vector<int> t[maxn]; void dfs(int now,int fa){
dfn[now] = ++cl;pt[now] = fa;
for(int i=;i<g[now].size();i++){
pair<int,int> pr = g[now][i];
if(pr.first == fa) continue;
if(!dfn[pr.first]){
t[now].push_back(pr.first);
chs[pr.second] = ;lnk[pr.first] = pr.second;
dfs(pr.first,now);
}
else{
if(dfn[pr.first] > dfn[now]) continue;
f[now]++; f[pr.first]--;
}
}
} int im[maxn];
void dfs2(int now){
for(int i=;i<t[now].size();i++){dfs2(t[now][i]); dd[now]+=dd[t[now][i]];}
dd[now] += f[now];
}
void dfs3(int now){
im[now] = im[pt[now]] + (dd[now] > );
for(int i=;i<t[now].size();i++){dfs3(t[now][i]);}
} void solve(int now){
if(dfn[e[now].from] < dfn[e[now].to]) swap(e[now].from,e[now].to);
int kk = im[e[now].from] - im[e[now].to];
if(kk == ){
int pla = e[now].from;
while(pla!=e[now].to){ans.push_back(lnk[pla]);pla = pt[pla];}
ans.push_back(now);
}
} void work(){
for(int i=;i<=n;i++) { if(!dfn[i]) dfs(i,),dfs2(i),dfs3(i); }
for(int i=;i<=m;i++){ if(!chs[i]) solve(i); }
sort(ans.begin(),ans.end());
printf("%d\n",ans.size());
for(int i=;i<ans.size();i++){
printf("%d ",ans[i]);
}
} int main(){
//freopen("1.in","r",stdin);
//freopen("1.out","w",stdout);
read();
work();
return ;
}

Codeforces962F Simple Cycles Edges 【双连通分量】【dfs树】的更多相关文章

  1. 点双连通分量F. Simple Cycles Edges

    F. Simple Cycles Edges time limit per test 2 seconds memory limit per test 256 megabytes input stand ...

  2. CF962F Simple Cycles Edges

    CF962F Simple Cycles Edges 给定一个连通无向图,求有多少条边仅被包含在一个简单环内并输出 \(n,\ m\leq10^5\) tarjan 首先,一个连通块是一个环,当且仅当 ...

  3. Simple Cycles Edges CodeForces - 962F(点双连通分量)

    题意: 求出简单环的所有边,简单环即为边在一个环内 解析: 求出点双连通分量,如果一个连通分量的点数和边数相等,则为一个简单环 点双连通分量  任意两个点都至少存在两条点不重复的路径  即任意两条边都 ...

  4. HDU4612 Warm up 边双连通分量&&桥&&树直径

    题目的意思很简单,给你一个已经连通的无向图,我们知道,图上不同的边连通分量之间有一定数量的桥,题目要求的就是要你再在这个图上加一条边,使得图的桥数目减到最少. 首先要做的就是找出桥,以及每个点所各自代 ...

  5. HDU 4612——Warm up——————【边双连通分量、树的直径】

    Warm up Time Limit:5000MS     Memory Limit:65535KB     64bit IO Format:%I64d & %I64u Submit Stat ...

  6. codeforces 962 F Simple Cycles Edges

    求简单环,即求点=边数的点双分量,加上判断点和边的模板即可 (简单环模板,区分与点双缩点) ; ], edgecnt, dfn[maxm], low[maxm], bcc_cnt, bccnum[ma ...

  7. Educational Codeforces Round 42 (Rated for Div. 2)F - Simple Cycles Edges

    http://codeforces.com/contest/962/problem/F 求没有被两个及以上的简单环包含的边 解法:双联通求割顶,在bcc中看这是不是一个简单环,是的话把整个bcc的环加 ...

  8. P2542 [AHOI2005]航线规划 LCT维护双连通分量

    \(\color{#0066ff}{ 题目描述 }\) 对Samuel星球的探险已经取得了非常巨大的成就,于是科学家们将目光投向了Samuel星球所在的星系--一个巨大的由千百万星球构成的Samuel ...

  9. 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 ...

随机推荐

  1. oracle 11g空表不能exp导出问题解决方案

    oracle 11g空表不能exp导出问题解决方案 最近由于要进行迁移服务器代码和数据库,突然发现导出的表少了,通过排查发现空表尽然没有exp导出,真是郁闷啊,虽然是空表没数据,但也不能没有啊,如何是 ...

  2. vue文档全局api笔记1

    全局api方法 1.Vue.extend(options) 请注意,extend创建的是一个组件构造器,而不是一个具体的组件实例.所以他不能直接在new Vue中这样使用: new Vue({comp ...

  3. hibernate坑边闲话

    使用hibernate各种各样的坑 Remember that ordinal parameters are 1-based node to traverse cannot be null 这两个错误 ...

  4. Lombok 安装、入门以及使用

    lombok 的官方网址:http://projectlombok.org/ lombok 安装    使用 lombok 是需要安装的,如果不安装,IDE 则无法解析 lombok 注解.先在官网下 ...

  5. Iar8.1安装包破解

    Iar8.1安装包链接链接:https://pan.baidu.com/s/1F6sxEcatk3_YPq47lvc8Mw 密码:mnlz 破解链接  https://www.cnblogs.com/ ...

  6. anaconda安装win10

    注意事项: 1.下载安装,双选勾勾 2.安装python3.5的版本 conda create -n tensorflow python=3.5 3.激活环境activate tensorflow 4 ...

  7. git reset的用法

    git reset三个选项 --mix,--hard,--soft 数据 针对每个选项都是操作这个文件. [root@centos demo]# git init Initialized empty ...

  8. Linux sed使用方法

    目录 sed处理流程 测试数据 sed命令格式 sed命令行格式 行定位 定位1行 定位区间行(多行) 定位某一行之外的行 定位有跨度的行 操作命令 -a (新增行) -i(插入行) -c(替代行) ...

  9. vue-cli 上传图片上传到OSS(阿里云)

    https://help.aliyun.com/document_detail/32068.html?spm=5176.doc32069.6.304.Qc4SUs(看) https://help.al ...

  10. 剑指offer(7)

    今天的几道题目都是关于斐波那契数列的. 题目1: 大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项(从0开始,第0项为0). n<=39 传统的方法采用递归函数,这种 ...