洛谷P3388 【模板】割点
2016-11-01 23:38
253 查看
给出一个n个点,m条边的无向图,求图的割点。
u是cut vertex的两个条件:
1.存在v使v及其所有后代没有反向边连回u的祖先
2.u是根且有两个以上子节点
dfs一遍
low[u]是u及其后代所能连回的最早祖先
没有dfn[v]就dfs(v),然后用low[v]更新low[u](v是u的后代)
否则v不是fa就用dfn[v]更新low[u](u可以连回v)【不能用low[v],因为low[v]包含v的后代能连回】
u是cut vertex的两个条件:
1.存在v使v及其所有后代没有反向边连回u的祖先
2.u是根且有两个以上子节点
dfs一遍
low[u]是u及其后代所能连回的最早祖先
没有dfn[v]就dfs(v),然后用low[v]更新low[u](v是u的后代)
否则v不是fa就用dfn[v]更新low[u](u可以连回v)【不能用low[v],因为low[v]包含v的后代能连回】
#include <iostream> #include <cstdio> #include <algorithm> #include <cstring> using namespace std; const int N=1e5+5,M=1e5+5,INF=1e9+5; inline int read(){ char c=getchar();int x=0,f=1; while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();} while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();} return x; } int n=0,m,u,v; struct edge{ int v,ne; }e[M<<1]; int h ,cnt=0; inline void ins(int u,int v){ cnt++; e[cnt].v=v;e[cnt].ne=h[u];h[u]=cnt; cnt++; e[cnt].v=u;e[cnt].ne=h[v];h[v]=cnt; } int dfn ,low ,dfc=0,iscut ; void dfs(int u,int fa){ dfn[u]=low[u]=++dfc; int child=0; for(int i=h[u];i;i=e[i].ne){ int v=e[i].v; if(!dfn[v]){ child++; dfs(v,u); low[u]=min(low[u],low[v]); if(low[v]>=dfn[u]) iscut[u]=1; }else if(dfn[v]<dfn[u]&&v!=fa) low[u]=min(low[u],dfn[v]); } if(fa==0&&child==1) iscut[u]=0; } int main(){ n=read();m=read(); for(int i=1;i<=m;i++){u=read();v=read();ins(u,v);} for(int i=1;i<=n;i++) if(!dfn[i]) dfs(i,0); int ans=0; for(int i=1;i<=n;i++) if(iscut[i]) ans++; printf("%d\n",ans); for(int i=1;i<=n;i++) if(iscut[i]) printf("%d ",i); }
相关文章推荐
- 割点 洛谷P3388 【模板】割点(割顶) 学习板子
- 洛谷P3388 【模板】割点(割顶)(tarjan求割点)
- 洛谷—— P3388 【模板】割点(割顶)
- 洛谷P3388 【模板】割点(割顶)
- 洛谷P3388 【模板】割点(割顶)
- 洛谷P3381 【模板】最小费用最大流(dijstra费用流)
- 洛谷P3384 【模板】树链剖分
- 洛谷.3919.[模板]可持久化数组(可持久化线段树/平衡树)
- 洛谷 P3390 【模板】矩阵快速幂
- [洛谷模板大赛]题解 模板整理QAQ
- 洛谷.3805.[模板]manacher算法
- 洛谷 3370 hash模板
- 洛谷 P3379 【模板】最近公共祖先(LCA)
- 洛谷 P3376 【模板】网络最大流
- 洛谷P3384【模板】树链剖分
- 洛谷 P3370 【模板】字符串哈希
- 洛谷 P3811 【模板】乘法逆元
- P3383 【模板】线性筛素数 洛谷
- 洛谷 P3383 【模板】线性筛素数
- 洛谷 P1439 【模板】最长公共子序列