题目大意:

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

题目分析:

  如果这道题我们掌握了点双连通分量,那么结论会很显然,找到每个点双,如果一个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. Python 内置库 sys用法

    sys模块功能众多,这边先学习几个常用的方法sys常见函数列表① sys.argv: 实现从程序外部向程序传递参数.其实sys.argv[]就是一个列表,里面的项为用户输入的参数,但是sys.argv ...

  2. Success Rate CodeForces - 807C (数学+二分)

    You are an experienced Codeforces user. Today you found out that during your activity on Codeforces ...

  3. ElasticSearch Nosql

    把 ElasticSearch 当成是 NoSQL 数据库 Elasticsearch 可以被当成一个 "NoSQL"-数据库来使用么? NoSQL 意味着在不同的环境下存在不同的 ...

  4. JavaScript动态修改html组件form的action属性

    用javaScript动态修改html组件form的action属性,可以在提交时再决定处理表单的页面. <%--JavaScript部分--%><script language=& ...

  5. 本地项目托管到github上

    一,步骤 1.在github上新建一个仓库 2.进入我的项目目录, git init //初始化本地仓库 3.git add . //把修改的代码提交到暂存区 4.git status 该命令会把你本 ...

  6. VS2008引入头文件包含目录和lib库目录

    全局级别的引入 为VS所有项目设置包含目录和库目录,对所有项目都有效 如下图所示:工具-选项-项目和解决方案-VC++目录-包含文件:在此添加头文件目录即可 工具-选项-项目和解决方案-VC++目录- ...

  7. Pseudo Registers

    Pseudoregister Description @ERR Last error value; the same value returned by the GetLastError() API ...

  8. vue处理异步数据踩过的坑

    在开发时,由于数据是异步的导致页面在render 时data是空值 出现报错和警告. 我是这么处理的 把data先写出一个空的完整结构.暂时是这么处理 或者用三元表达式进行赋值监听.data ?myd ...

  9. asp.net core发布到linux

    在发布到linux的过程中出现两个问题现在总结一下: 我的虚拟机是安装到本机上面的,所以,应该在虚拟机的设置里面设置端口映射.具体设置如下: 选择vm上方的编辑 在弹出的框中选择VMnet8,点击下方 ...

  10. [转帖]IP /TCP协议及握手过程和数据包格式中级详解

    IP /TCP协议及握手过程和数据包格式中级详解 https://www.toutiao.com/a6665292902458982926/ 写的挺好的 其实 一直没闹明白 网络好 广播地址 还有 网 ...