P3388 【模板】割点(割顶)
2017-11-25 17:31
253 查看
P3388 【模板】割点(割顶)
题目背景
割点
题目描述
给出一个n个点,m条边的无向图,求图的割点。
输入输出格式
输入格式:
第一行输入n,m
下面m行每行输入x,y表示x到y有一条边
输出格式:
第一行输出割点个数
第二行按照节点编号从小到大输出节点,用空格隔开
输入输出样例
输入样例#1: 复制6 7 1 2 1 3 1 4 2 5 3 5 4 5 5 6输出样例#1: 复制
1 5
说明
n,m均为100000
tarjan 图不一定联通!!!
分析
tarjan求割点
code
#include<cstdio> #include<algorithm> #include<cstring> #include<cmath> #include<cstdlib> using namespace std; const int N = 100100; struct Edge{ int to,nxt; }e[N<<1]; int head ,dfn ,low ; bool iscut ; int tn,tot; inline char nc() { static char buf[100000],*p1 = buf,*p2 = buf; return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2) ? EOF : *p1++; } inline int read() { int x = 0,f = 1;char ch = nc(); for (; ch<'0'||ch>'9'; ch = nc()) if (ch=='-') f = -1; for (; ch>='0'&&ch<='9'; ch = nc()) x = x*10+ch-'0'; return x * f; } void add_edge(int u,int v) { e[++tot].to = v,e[tot].nxt = head[u],head[u] = tot; } void tarjan(int u,int fa) { low[u] = dfn[u] = ++tn; int cnt_son = 0; for (int i=head[u]; i; i=e[i].nxt) { int v = e[i].to; if (!dfn[v]) { cnt_son++; tarjan(v,u); low[u] = min(low[u],low[v]); if (low[v] >= dfn[u]) iscut[u] = true; } else if (dfn[v] < dfn[u] && v != fa) low[u] = min(low[u],dfn[v]); } if (fa<0 && cnt_son==1) iscut[u] = false; } int main() { int n = read(),m = read(); for (int u,v,i=1; i<=m; ++i) { u = read(),v = read(); add_edge(u,v),add_edge(v,u); } for (int i=1; i<=n; ++i) if (!dfn[i]) tarjan(i,-1); 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); return 0; }
相关文章推荐
- 洛谷P3388 【模板】割点(割顶)(tarjan求割点)
- 割点 洛谷P3388 【模板】割点(割顶) 学习板子
- 洛谷P3388 【模板】割点(割顶)
- 洛谷—— P3388 【模板】割点(割顶)
- 洛谷P3388 【模板】割点(割顶)
- P3388 【模板】割点(割顶)
- 无向图的割顶和桥,无向图的双连通分量入门详解及模板
- 【模板】无向图的割顶
- 洛谷P3388 【模板】割点
- P3388 【模板】割点
- (模板)割点(割顶)tarjan类算法
- 【模板】割点(割顶)
- 图论模板 求割顶/判断二分图
- poj1144(求割顶模板题)
- 图论模板 求割顶/判断二分图
- luogu P3388 【模板】割点(割顶)
- 图论算法-Tarjan模板 【缩点;割顶;双连通分量】
- 洛谷3388 割点(割顶)模板
- 深夜敲模板_4——无向图的割顶和桥
- 洛谷3388:【模板】割点(割顶)——题解