博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
洛谷P3388 【模板】割点(割顶)
阅读量:4502 次
发布时间:2019-06-08

本文共 1389 字,大约阅读时间需要 4 分钟。

题目背景

割点

题目描述

给出一个\(n\)个点,\(m\)条边的无向图,求图的割点。

输入输出格式

输入格式:

第一行输入\(n,m\)

下面\(m\)行每行输入\(x,y\)表示\(x\)\(y\)有一条边

输出格式:

第一行输出割点个数

第二行按照节点编号从小到大输出节点,用空格隔开

输入输出样例

输入样例#1:

6 71 21 31 42 53 54 55 6

输出样例#1:

1 5

说明

对于全部数据,\(n \le 20000\)\(m \le 100000\)

点的编号均大于\(0\)小于等于\(n\)

tarjan图不一定联通。

思路:一道求割点的模板题,如果一个点为割点,当且仅当去掉这个点和连向这个点的边之后,整张图不再联通。那么问题可以转化为,一个点的子结点必须经过这个点才能到达其他的不是这个点的子结点的点,如果这个点是根,那么只需要判断它的孩子数目是否大于等于2即可,如果是,则这个点一定是割点。

代码:

#include
#include
#define maxn 20007using namespace std;int n,m,head[maxn],dfn[maxn],low[maxn],bel[maxn],size[maxn],num,cnt,js,zrj;bool vis[maxn],bj[maxn];struct node { int v,nxt;}e[200007];inline void ct(int u, int v) { e[++num].v=v; e[num].nxt=head[u]; head[u]=num;}void tarjan(int u, int fa) { int child=0; dfn[u]=low[u]=++cnt; for(int i=head[u];i;i=e[i].nxt) { int v=e[i].v; if(!dfn[v]) { tarjan(v, fa); low[u]=min(low[u],low[v]); if(u!=fa&&low[v]>=dfn[u]) bj[u]=1; if(u==fa) child++; } low[u]=min(low[u],dfn[v]); } if(u==fa&&child>=2) bj[u]=1;}int main() { scanf("%d%d",&n,&m); for(int i=1,u,v;i<=m;++i) { scanf("%d%d",&u,&v); ct(u,v),ct(v,u); } for(int i=1;i<=n;++i) if(!dfn[i]) tarjan(i,i); for(int i=1;i<=n;++i) if(bj[i]) zrj++; printf("%d\n",zrj); for(int i=1;i<=n;++i) if(bj[i]) printf("%d ",i); printf("\n"); return 0;}

转载于:https://www.cnblogs.com/grcyh/p/10142830.html

你可能感兴趣的文章
C#导出EXCEL方法总结
查看>>
【poj3342】 Party at Hali-Bula
查看>>
SCM基础之组织结构设计
查看>>
「OC」@property @synthesize和id
查看>>
(爱加密系列教程六)Android代码注入大揭秘
查看>>
ERP程序开发中遇到的六种错误
查看>>
Hibernate_拦截器与日志文件
查看>>
2-Sixteenth Scrum Meeting-20151216
查看>>
Visual Studio 2015、2013、2012、2010、2008、2005各版本下载+有效密钥激活
查看>>
Appium键盘操作
查看>>
常见排序
查看>>
jsp自动生成验证码
查看>>
射频识别技术漫谈(12)——三次相互认证【worldsing笔记】
查看>>
flume收集日志无法在HDFS上存储
查看>>
IO多路复用(select)
查看>>
HDUOJ -----Color the ball
查看>>
HashMap
查看>>
docker建立一个博客的过程
查看>>
基于jquery带时间轴的图片轮播切换代码
查看>>
自已在别人基础上封装的AES数法 C++
查看>>