题目链接:https://www.luogu.com.cn/problem/P3388

tarjan算法果然牛逼,时间复杂度是O(|V|+|E|),所以1e4个结点2e5条边的图完全不在话下orz orz

一个无向图求割点,该图不一定连通,所以要对没有访问过的点继续tarjan,这时候我就wa了几次,因为之前只用过一次tarjan,在参数设置里面我默认了从u=1开始建dfs树。每次只有根节点的father值等于其编号,这样就能唯一地标识它,学到了。其次在下面证明 tarjan中如果在处理回退边的时候用的是①、 low[u]=min(low[u],low[v])(强连通分量的用法)而不是②、low[u]=min(low[u],dfn[v])的话将会出现什么样的错误。

我们模拟两种Tarjan算法,一种是low[u] = min( low[u], low[v] );,一种是low[u] = min( low[u], dfn[v] );。(证明参考洛谷博客)

第1种:

① dfs(1),dfn[1] = 1,low[1] = 1。

② dfs(2),dfn[2] = 2,low[2] = 2。

③ dfs(3),dfn[3] = 3,low[3] = 3。

④ 发现回边 3 -> 1,low[3] = 1。

⑤ dfs(4),dfn[4] = 4,low[4] = 4。

⑥ dfs(5),dfn[5] = 5,low[5] = 5。

⑦ 发现回边 5 -> 3,low[5] = 1。

⑧ dfs(5)结束,回到dfs(4),low[4] = 1。

⑨ dfs(4)结束,回到dfs(3),low[3] = 1。

⑩ dfs(3)结束,至此未发现割点。

第2种:

① dfs(1),dfn[1] = 1,low[1] = 1。

② dfs(2),dfn[2] = 2,low[2] = 2。

③ dfs(3),dfn[3] = 3,low[3] = 3。

④ 发现回边 3 -> 1,low[3] = 1。

⑤ dfs(4),dfn[4] = 4,low[4] = 4。

⑥ dfs(5),dfn[5] = 5,low[5] = 5。

⑦ 发现回边 5 -> 3,low[5] = 3。

⑧ dfs(5)结束,回到dfs(4),low[4] = 3。

⑨ dfs(4)结束,回到dfs(3),low[4] >= dfn[3],发现割点3,low[3] = 1。

而这个图中,正确答案是:3是割点。

所以第1种方法就被我们愉快地Hack掉了。

其次,我在处理回退边的时候在条件中加上了dfn[v]<dfn[u],时间效率提高了大约10%,这是显而易见的,因为只有回退边到达的结点在父节点之前被访问,而且这个结点还不是已经处理过的fa结点。

代码如下:

 #include<bits/stdc++.h>
using namespace std;
typedef unsigned int ui;
typedef long long ll;
typedef unsigned long long ull;
#define pf printf
#define mem(a,b) memset(a,b,sizeof(a))
#define prime1 1e9+7
#define prime2 1e9+9
#define pi 3.14159265
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define scand(x) scanf("%llf",&x)
#define f(i,a,b) for(int i=a;i<=b;i++)
#define scan(a) scanf("%d",&a)
#define mp(a,b) make_pair((a),(b))
#define P pair<int,int>
#define dbg(args) cout<<#args<<":"<<args<<endl;
#define inf 0x3f3f3f3f
const int maxn=2e4+;
int n,m,t;
inline int read(){
int ans=,w=;
char ch=getchar();
while(!isdigit(ch)){if(ch=='-')w=-;ch=getchar();}
while(isdigit(ch))ans=(ans<<)+(ans<<)+ch-'',ch=getchar();
return ans*w;
}
int low[maxn],dfn[maxn],iscut[maxn],head[maxn],nxt[];
int cnt=;
int ans=;
struct node{
int u,v;
}p[];
int e=;
void addedge(int x,int y)
{
p[e].u=x;
p[e].v=y;
nxt[e]=head[x];
head[x]=e++;
}
void tarjan(int u,int fa)
{
dfn[u]=low[u]=++cnt;
int child=;
for(int i=head[u];~i;i=nxt[i])
{
int v=p[i].v;
if(!dfn[v])
{
if(fa==u)child++;
tarjan(v,u);
low[u]=min(low[v],low[u]);
if(low[v]>=dfn[u]&&u!=fa)iscut[u]=;
}
else if(dfn[v]<dfn[u]&&v!=fa)
{
low[u]=min(low[u],dfn[v]);
}
}
if(u==fa&&child>)iscut[u]=;
}
int main()
{
//freopen("input.txt","r",stdin);
//freopen("output.txt","w",stdout);
std::ios::sync_with_stdio(false);
n=read(),m=read();
int x,y;
cnt=;
ans=;
mem(low,);
mem(dfn,);
mem(iscut,);
mem(head,-);
mem(nxt,-);
f(i,,m)
{
x=read(),y=read();
addedge(x,y);
addedge(y,x);
}
f(i,,n)
{
if(!dfn[i])tarjan(i,i);//图不一定连通,所以每个连通分量都要tarjan一次
}
f(i,,n)
{
if(iscut[i])ans++;
}
pf("%d\n",ans);
f(i,,n)
if(iscut[i])pf("%d ",i);
return ;
}

洛谷3388 tarjan割点的更多相关文章

  1. 洛谷3388 【模板】割点 tarjan算法

    题目描述 给出一个n个点,m条边的无向图,求图的割点. 关于割点 在无向连通图中,如果将其中一个点以及所有连接该点的边去掉,图就不再连通,那么这个点就叫做割点(cut vertex / articul ...

  2. NOIP2017提高组Day1T3 逛公园 洛谷P3953 Tarjan 强连通缩点 SPFA 动态规划 最短路 拓扑序

    原文链接https://www.cnblogs.com/zhouzhendong/p/9258043.html 题目传送门 - 洛谷P3953 题目传送门 - Vijos P2030 题意 给定一个有 ...

  3. 洛谷 - P3469 - BLO-Blockade - 割点

    https://www.luogu.org/problem/P3469 翻译:一个原本连通的无向图,可以删除图中的一个点,求因为删除这个点所导致的不连通的有序点对的数量.或者说,删去这个点之后,各个连 ...

  4. 【Tarjan】洛谷P3379 Tarjan求LCA

    题目描述 如题,给定一棵有根多叉树,请求出指定两个点直接最近的公共祖先. 输入输出格式 输入格式: 第一行包含三个正整数N.M.S,分别表示树的结点个数.询问的个数和树根结点的序号. 接下来N-1行每 ...

  5. 洛谷P1073 Tarjan + 拓扑排序 // 构造分层图

    https://www.luogu.org/problemnew/show/P1073 C国有 n n个大城市和 mm 条道路,每条道路连接这 nn个城市中的某两个城市.任意两个城市之间最多只有一条道 ...

  6. 「洛谷3469」「POI2008」BLO-Blockade【Tarjan求割点】

    题目链接 [洛谷传送门] 题解 很显然,当这个点不是割点的时候,答案是\(2*(n-1)\) 如果这个点是割点,那么答案就是两两被分开的联通分量之间求组合数. 代码 #include <bits ...

  7. ⌈洛谷5058⌋⌈ZJOI2004⌋嗅探器【Tarjan】

    题目连接 [洛谷传送门] [LOJ传送门] 题目描述 某军搞信息对抗实战演习,红军成功地侵入了蓝军的内部网络,蓝军共有两个信息中心,红军计划在某台中间服务器上安装一个嗅探器,从而能够侦听到两个信息中心 ...

  8. tarjan算法比较详细的讲解&&tarjan常见疑难解答&&洛谷P2002 消息扩散题解

    因为有大佬写的比我更长更具体,所以我也就写写总结一下了 引入: 众所周知,很多图中有个东西名叫环. 对于这个东西很多算法都很头疼.(suchas 迪杰斯特拉) 更深层:环属于强联通分量(strongl ...

  9. 洛谷 P2194 HXY烧情侣【Tarjan缩点】 分析+题解代码

    洛谷 P2194 HXY烧情侣[Tarjan缩点] 分析+题解代码 题目描述: 众所周知,HXY已经加入了FFF团.现在她要开始喜(sang)闻(xin)乐(bing)见(kuang)地烧情侣了.这里 ...

随机推荐

  1. 【pic+js+gh】免费高速图床方案

    本文用到的工具或网站 PicGo jsdelivr github 速度对比 Github的速度: jsdelivrCDN的速度: 下载PicGo 首先进入PicGo的下载地址 选择最新版本下载,根据自 ...

  2. Blind Estimation and Detection of Space-Time Trellis Coded Transmissions over the Rayleigh Fading MIMO Channel

    目录 文章来源 摘要 基本概念 粒子滤波 时间序列模型 系统模型 通信系统 经典状态空间表示 论文所提出的状态空间表示 借鉴之处 文章来源 IEEE TRANSACTIONS ON COMMUNICA ...

  3. Ubuntu 16.04 apt 国内源

    一.推荐几个 Ubuntu 16.04 国内的 apt 源 1. 阿里源 # deb cdrom:[Ubuntu 16.04 LTS _Xenial Xerus_ - Release amd64 (2 ...

  4. Spring常见注解

    @Autowired @Resource @Component:类加上@Component注解,即表明此类是bean @Aspect 注解表示这是一个切面 @Around(value = " ...

  5. 正式学习MVC 05

    1.剃须刀模板razor的使用 1)混编 循环语法 @model List<MVCStudy.Models.Student> @{ ViewBag.Title = "List&q ...

  6. html/css系列-图片上下居中

    本文详情:http://www.zymseo.com/276.html图片上下居中的问题常用的几种方法:图片已知大小和未知大小,自行理解 .main{ width: 400px;height: 400 ...

  7. js对象中关于this关键字的作用

    前两天在前端群看到群友问的一个问题,问题如下: var Name = 'window'; var obj = { Name:'obj字符串', getName:function(){ console. ...

  8. Windows下利用virtualenvwrapper指定python版本创建虚拟环境

    默认已安装virtualenvwrapper 一.添加环境变量(可选) 在系统环境变量中添加 WORKON_HOME ,用来指定新建的虚拟环境的存储位置,如过未添加,默认位置为 %USERPROFIL ...

  9. 【django】 接收所有文件,前端展示文件(包括视频,文件,图片)ajax请求

    如果是后台上传文件: setting配置: STATIC_URL = '/static/' STATICFILES_DIRS = [ os.path.join(BASE_DIR, 'static'), ...

  10. Let’s Encrypt https证书安装

    我的博客: https://www.seyana.life/post/15 现在已经有很多的免费ssl证书提供商,国内的也有, 不过国内政策要求还要把key给他们, 我们还是用Let's Encryp ...