无重边无向连通图的割点和桥
2016-05-17 11:15
267 查看
#include<cstdio> #include<cstring> #include<vector> #include<algorithm> using namespace std; vector<vector<int> > g; int dfn[11000];//节点在dfs过程中的访问序号(也可以叫做开始时间) int low[11000];//节点的子树中能够通过非父子边追溯到的最早的节点的dfs开始时间 int fa[11000];//dfs树中每个点的父节点 int viscv[11000];//标记是否为割点 int ntime;//dfs中记录时间 int n,m;//点数和边数 void tarjan(int u,int father)//father是u的父节点 { fa[u]=father; int i; low[u]=dfn[u]=ntime++; for(i=0;i<g[u].size();i++) { int v=g[u][i]; if(!dfn[v]) { tarjan(v,u); low[u]=min(low[u],low[v]); } else if(father!=v) { low[u]=min(low[u],dfn[v]); } } } void solve() { int sontree=0;//dfs树中根节点的子树的数目 int i; tarjan(1,0); for(i=2;i<=n;i++) { int v=fa[i]; if(v==1) sontree++; else { if(dfn[v]<=low[i]) viscv[v]=1; } } if(sontree>1) viscv[1]=1; for(i=1;i<=n;i++) { if(viscv[i]) printf("%d\n",i); } for(i=1;i<=n;i++) { int v=fa[i]; if(v>0&&dfn[v]<low[i]) printf("%d %d\n",v,i); } } int main() { int u,v,i; ntime=1; while(scanf("%d%d",&n,&m)!=EOF) { g.clear(); g.resize(11000); ntime=1; for(i=0;i<m;i++)//点编号是从1开始的 { scanf("%d%d",&u,&v); g[u].push_back(v); g[v].push_back(u); } memset(dfn,0,sizeof(dfn)); memset(low,0,sizeof(low)); memset(fa,0,sizeof(fa)); memset(viscv,0,sizeof(viscv)); solve(); } return 0; }
相关文章推荐
- Linux 下 Mysql 5.7 的安装
- 实现Android应用自动检查更新并且下载
- web程序定时器
- 使用MyBatis搭建一个访问mysql数据库的简单示例
- hashset原理
- java垃圾回收机制
- uva 11549
- 【js学习1】JavaScript实现&JavaScript插入
- C++中类型转换—static_cast,dynamic_cast,const_cast
- springmvc_hibernate的pom文件
- Linux系统编程学习笔记-open函数
- 用GDB调试程序(二)
- HDOJ1753 大浮点数相加
- [HDFS]HDFS的运行原理
- jsp trimDirectiveWhitespaces ="true"(删除空白行)
- ArrayList 源码解析
- CentOS6.5 安装Spark集群
- Docker Registry搭建私有仓库
- Python 装饰器简单介绍
- LeetCode刷题 -- Best Time to Buy and Sell Stock