题目连接:http://codeforces.com/contest/962/problem/F

题目大意是定义一个simple cycle为从一个节点开始绕环走一遍能经过simple cycle内任何一个节点,并且不超过一次。

因为是无向图,而且是环,即为连通分量,所以模型转化为求点双连通分量,依据题意求得的点双连通分量需要满足题目simple cycle的定义,所以当一个点双连通分量的边数量和点数量相等时才能构成simple cycle,在tarjan求割点的时候,需要存储点双联通分量的点和边的数量,最后判断一下是否相等,整体存储起来,最终排序一下满足题意的input边的目录。

AC代码:

#include<iostream>
#include<stack>
#include<algorithm>
#include<vector>
#include<set>
#include<map>
using namespace std;
const int maxn = 1e5+7;
struct node{
vector<int> vex;
vector<int> num;
};//建图 vex为node[i]连接的节点,num储存node[i]和vex内节点连接边的序号
struct edge{
int a,b,id;
}E[maxn*2];//a为边的起点,b为边的终点,id为边的输入目录
stack<int> stk;//储存边的目录的栈
node g[100005];
int n,m,tot;
int BCC = 0;//统计BCC
int visit[200014],dfn[100005],low[100005],iscut[100005];
int bcc[100005];
vector<int> ans;
void tarjan(int x,int fa){
int child = 0;
low[x] = dfn[x] = ++tot;
for(int i = 0;i<g[x].vex.size() ;i++){
int tedge = g[x].num[i]; //边序号,后续可以由边序号作为索引找到该边的id(目录)
int temp = E[tedge].b;//temp为边的终点
if(temp == fa){
continue;
}
if(visit[tedge]){
continue;
}
visit[tedge] = visit[tedge^1] = 1;//标记双向边已经访问过
stk.push(tedge);
if(!dfn[temp]){
child++;
tarjan(temp,x);
low[x] = min(low[x],low[temp]);
if(low[temp]>=dfn[x])
{//找到割点,即找到一个点双连通分量
iscut[x] = 1;
BCC++;
set<int> Vset;//存该BCC的点
set<int> Eset;// 存该BCC的边
Vset.insert(x);
int s;
do{
s = stk.top();
stk.pop();
Eset.insert(E[s].id);//加入边的目录id
Vset.insert(E[s].b);//加入边的终点
}while(s!=tedge); if(Eset.size() == Vset.size()){
for(set<int>::iterator it=Eset.begin();it!=Eset.end();it++)
ans.push_back(*it);//以题意要求判断是否为simple cycle
}
}
}
else
{
low[x] = min(low[x],dfn[temp]);
}
}
if(fa == -1 && child <2){
iscut[x] = 0;
}
}
int edgenum = 0;//边的序号从0开始,因为是建立双向边所以两条边标记的序号是异或关系,由边序号可以找到该边的id
void addedge(int u,int v,int id){
E[edgenum].a = u;
E[edgenum].b = v;
g[u].num.push_back(edgenum);
E[edgenum++].id = id;
}
int main(){
int n,m;
cin>>n>>m;
for(int i = 1;i<=m;i++){
int u,v;
cin>>u>>v;
addedge(u,v,i);
addedge(v,u,i);
g[u].vex.push_back(v);
g[v].vex.push_back(u);
}
for(int i = 1;i<=n;i++){
if(!dfn[i]){
tarjan(i,-1);
}
}
int cut = 0;
for(int i = 1;i<=n;i++){
if(iscut[i] == 1){
cut++;
}
}
sort(ans.begin(),ans.end());
cout<<ans.size()<<endl;
for(int i=0;i<(int)ans.size();i++)
cout<<ans[i]<<" ";
//cout<<BCC<<" "<<cut;
return 0;
}

codeforces 962F.simple cycle(tarjan/点双连通分量)的更多相关文章

  1. 【Codefoces487E/UOJ#30】Tourists Tarjan 点双连通分量 + 树链剖分

    E. Tourists time limit per test: 2 seconds memory limit per test: 256 megabytes input: standard inpu ...

  2. Codeforces 521E - Cycling City(点双连通分量+分类讨论)

    Codeforces 题面传送门 & 洛谷题面传送门 大家都是暴力找生成树然后跳路径,代码不到 50 行(暴论)的一说--好,那本蒟蒻决定提供一种代码 150 行,但复杂度也是线性的分类讨论做 ...

  3. CodeForces 97 E. Leaders(点双连通分量 + 倍增)

    题意 给你一个有 \(n\) 个点 \(m\) 条边的无向图,有 \(q\) 次询问,每次询问两个点 \(u, v\) 之间是否存在长度为奇数的简单路径. \(1 \le n, m, q \le 10 ...

  4. [LA3523/uva10195]圆桌骑士 tarjan点双连通分量+奇环定理+二分图判定

    1.一个环上的各点必定在同一个点双连通分量内: 2.如果一个点双连通分量是二分图,就不可能有奇环: 最基本的二分图中的一个环: #include<cstdio> #include<c ...

  5. POJ 3177 Redundant Paths (tarjan边双连通分量)

    题目连接:http://poj.org/problem?id=3177 题目大意是给定一些牧场,牧场和牧场之间可能存在道路相连,要求从一个牧场到另一个牧场要有至少两条以上不同的路径,且路径的每条pat ...

  6. Codeforces962F Simple Cycles Edges 【双连通分量】【dfs树】

    题目大意: 给出一个无向图,问有哪些边只属于一个简单环. 题目分析: 如果这道题我们掌握了点双连通分量,那么结论会很显然,找到每个点双,如果一个n个点的点双正好由n条边构成,那么这些边都是可以的. 这 ...

  7. 【BZOJ-1123】BLO Tarjan 点双连通分量

    1123: [POI2008]BLO Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 970  Solved: 408[Submit][Status][ ...

  8. 图连通性【tarjan点双连通分量、边双联通分量】【无向图】

    根据 李煜东大牛:图连通性若干拓展问题探讨 ppt学习. 有割点不一定有割边,有割边不一定有割点. 理解low[u]的定义很重要. 1.无向图求割点.点双联通分量: 如果对一条边(x,y),如果low ...

  9. tarjan 边双连通分量 对点进行分组 每组点都在一个双连通分量里边

    int dfn[N],low[N],id[N],s[N],p,num,t,son[N];//dfn记录dfs时间戳//low代表当前点到达的最小时间戳,id对点进行分组编号.num是时间戳//s临时存 ...

随机推荐

  1. python3运行时候报错集锦:读取文件报错

    1.关于读取文件报错: 命令执行到cf.read(cfpath),出现如下报错:UnicodeDecodeError: 'gbk' codec can't decode byte 0xa0 in po ...

  2. Linux命令——细节

    echo -n 不换行输出 echo -e 处理特殊字符 若字符串中出现以下字符,则特别加以处理,而不会将它当成一般文字输出: \a 发出警告声: \b 删除前一个字符: \c 最后不加上换行符号:  ...

  3. jQuery---创建和添加节点

    创建和添加节点 //创建jq对象 var $li = $('<a href="http://web.itcast.cn" target="_blank"& ...

  4. Matlab技巧1:在同一坐标系上绘制两个函数图像

    x=-:; y1=sqrt(*abs(x)-x.^); y2=asin(abs(x)-)-pi/; plot(x,y1,'r',x,y2,'b') grid 程序结果:

  5. 异常处理_python

    一.异常处理格式: name=[1,2]data={}try: name[3] data['name']except (KeyError,IndexError) as e : #捕捉指定的几个错误类型 ...

  6. Struts2学习-jsp中超链接传参问题

    今天在学习过程中对struts2中超链接的传参问题产生了一些疑惑,不明白jsp中的超链接如何将参数传到Action方法中去的. <s:iterator value="categorys ...

  7. [Arc068D/At2299] Card Eater - 结论

    [Arc068D/At2299] 有一堆牌,每张牌上有一个数字. 每次可以取出其中 \(3\) 张,丢掉数字最大的和数字最小的牌,把中间那张再放回牌堆. 要求最后所有剩余牌上的数字互不相同,求最多能剩 ...

  8. Postgresql Json Sql

    a detailed website about json sql query; official website: here, chinese version: here Json query: - ...

  9. java mail发送html格式的邮件

    // 获取系统属性 Properties properties = System.getProperties(); // 设置邮件服务器 properties.setProperty("ma ...

  10. 【转载】python中math模块常用的方法

    转自:https://www.cnblogs.com/renpingsheng/p/7171950.html ceil #取大于等于x的最小的整数值,如果x是一个整数,则返回x ceil(x) Ret ...