题目大意:

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

题目分析:

  如果这道题我们掌握了点双连通分量,那么结论会很显然,找到每个点双,如果一个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. Linux Docker命令

    命令查看你当前的内核版本:uname -r yum 包更新到最新:yum update 安装需要的软件包, yum-util 提供yum-config-manager功能,另外两个是devicemap ...

  2. 领域驱动设计(DDD:Domain-Driven Design) 介绍

    Eric Evans的“Domain-Driven Design领域驱动设计”简称DDD,Evans DDD是一套综合软件系统分析和设计的面向对象建模方法,本站Jdon.com是国内公开最早讨论DDD ...

  3. linux screen 工具

    一.背景 系统管理员经常需要SSH 或者telent 远程登录到Linux 服务器,经常运行一些需要很长时间才能完成的任务,比如系统备份.ftp 传输等等.通常情况下我们都是为每一个这样的任务开一个远 ...

  4. H5 55-行高

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  5. SVN插件和Tomcat插件地址

    SVN插件: http://subclipse.tigris.org/update_1.8.x Tomcat插件: http://tomcatplugin.sf.net/update 备注:如果svn ...

  6. 用python实现一个回文数

    判断一个整数是否是回文数.回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数. 示例 1: 输入: 121 输出: true 示例 2: 输入: -121 输出: false 解释: 从左向 ...

  7. DevOps工程师到底做些什么?

    我们之前已经听到很多谈论DevOps和DevOps世界的最新趋势的事情,但是就DevOps工程师本身,到底干些什么呢? 在最纯粹的存在形式上来说,DevOps工程师是为了加快开发和运营团队之间的交付效 ...

  8. Kernel Functions-Introduction to SVM Kernel & Examples - DataFlair

    Kernel Functions-Introduction to SVM Kernel & Examples - DataFlairhttps://data-flair.training/bl ...

  9. ipython安装( jupyter)

    生产环境:win10 64位 pip的版本不是最新的,输入命令 python -m pip install --upgrade pip 更新我们的pip,pip不是最新的也会导致安装不了ipython ...

  10. IdentityServer4【Topic】之保护APIs

    Protecting APIs 保护api 默认情况下IdentityServer将access token发布成JWT(json web token)格式的. 现在,每个相关的平台都支持验证JWT令 ...