洛谷P3388 【模板】割点(割顶)
2018-02-24 17:04
337 查看
割顶
题目传送门割顶的定义:
对于无向图,如果删除某个点u后,连通分量的数目增加,称u为图的关节点或割点。对于连通图来说,删除割点后,图将变得不再连通。
怎么求无向图的割顶呢?
如果节点xx的子节点vv满足low[v]≥dfn[x]low[v]≥dfn[x],那么xx就是一个割顶。(当low[v]≥dfn[x]low[v]≥dfn[x]时,说明节点vv的回路在xx的下面,当xx被删除时,vv就不能和xx的祖先联通)
特别的,当根节点是割顶时需满足其子节点个数>1。
代码:
#include<cctype> #include<cstdio> #include<cstring> #include<algorithm> #define N 100005 #define F inline using namespace std; struct edge{ int next,to; }ed[N<<1]; int n,m,p,ans,k,h ,low ,dfn ; bool f ; F char readc(){ static char buf[100000],*l=buf,*r=buf; if (l==r) r=(l=buf)+fread(buf,1,100000,stdin); if (l==r) return EOF; return *l++; } F int _read(){ int x=0; char ch=readc(); while (!isdigit(ch)) ch=readc(); while (isdigit(ch)) x=(x<<3)+(x<<1)+(ch^48),ch=readc(); return x; } F void writec(int x){ if (x>9) writec(x/10); putchar(x%10+48); } F void addedge(int x,int y){ ed[++k]=(edge){h[x],y},h[x]=k; } void Tarjan(int x,int e){ int sum=0; bool flag=false; dfn[x]=low[x]=++p; for (int i=h[x],v;i;i=ed[i].next) if (i!=(e^1)) if (!dfn[v=ed[i].to]){ Tarjan(v,i),low[x]=min(low[x],low[v]); if (low[v]>=dfn[x]) flag=true; sum++; } else low[x]=min(low[x],dfn[v]); if ((!e&&sum>1)||(e&&flag)) ans++,f[x]=true; } int main(){ n=_read(),m=_read(),k=1; for (int i=1,x,y;i<=m;i++) x=_read(),y=_read(),addedge(x,y),addedge(y,x); for (int i=1;i<=n;i++) if (!dfn[i]) Tarjan(i,0); writec(ans),putchar('\n'); for (int i=1;i<=n;i++) if (f[i]) writec(i),putchar(' '); return putchar('\n'),0; }
相关文章推荐
- 洛谷—— P3388 【模板】割点(割顶)
- 洛谷P3388 【模板】割点(割顶)
- 洛谷P3388 【模板】割点(割顶)(tarjan求割点)
- 割点 洛谷P3388 【模板】割点(割顶) 学习板子
- 洛谷3388:【模板】割点(割顶)——题解
- 洛谷3388 割点(割顶)模板
- 洛谷3388 【模板】割点(割顶)
- 洛谷P3388 【模板】割点
- P3388 【模板】割点(割顶)
- P3388 【模板】割点(割顶)
- P3378 堆【模板】 洛谷
- 洛谷在线测试P3378_模板堆
- P3367 并查集【模板】 洛谷
- 洛谷 P3384 【模板】树链剖分
- 洛谷 P2634 BZOJ 2152 【模板】点分治(聪聪可可)
- [洛谷]P3371 单源最短路径模板 SPFA
- 洛谷P2341 受欢迎的牛——Tarjan+缩点模板
- P3372 【模板】线段树 1 洛谷
- [洛谷3812]【模板】线性基
- 洛谷P3386【模板】二分图匹配