Blockade -tarjan求割点

2024-04-13 13:38
文章标签 tarjan blockade 求割点

本文主要是介绍Blockade -tarjan求割点,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

链接:https://ac.nowcoder.com/acm/problem/50412
来源:牛客网

题目描述

Byteotia城市有n个城镇,m条双向道路。每条道路连接两个不同的城镇,没有重复的道路,所有城镇连通。
输出n个数,代表如果把第i个点去掉,将有多少对点不能互通。

输入描述

输入n,m及m条边。

输出描述

输出n个数,代表如果把第i个点去掉,将有多少对点不能互通。

分析

tarjan判断割点,和蓝书上面的BLO有点类似,区别就是BLO是去边,这里是去点

首先我们可以判断,如果一个点是不是割点,那么即使这个点去除,也不会影响整张图的连通性,所以仅仅是被删除的点和其他点不能进行连接,答案为2 * (n - 1)

如果一个点是割点的话,那么去掉这个点就可以把这张图分成几个树形结构,任意两个树形结构之间不能进行连接,所以我们只需要求树的大小即可

代码

#include <cstring>
#include <iostream>using namespace std;
typedef long long ll;const int N = 1e5 + 10, M = 1e6 + 10;int n,m;
int h[N],ne[M],e[M],idx;
int dfn[N],low[N],ti;
int root;
ll ans[N];
ll Size[N];
bool st[N];void add(int x,int y){e[idx] = y,ne[idx] = h[x],h[x] = idx++;
}void tarjan(int u){dfn[u] = low[u] = ++ti;int cnt = 0;Size[u] = 1;ll sum = 0;for(int i = h[u];~i;i = ne[i]){int j = e[i];if(!dfn[j]){tarjan(j);Size[u] += Size[j];low[u] = min(low[u],low[j]);if(low[j] >= dfn[u]){cnt++;sum += Size[j];if(u != root || cnt > 1) st[u] = true;ans[u] += Size[j] * (n - Size[j]);}}else low[u] = min(low[u], dfn[j]);}if(!st[u]) ans[u] = 2 * (n - 1);else ans[u] += 1ll * (n - 1) + (n - 1 - sum) * (sum + 1);
}int main(){scanf("%d%d",&n,&m);memset(h,-1,sizeof h);while(m--){int a,b;scanf("%d%d",&a,&b);add(a,b),add(b,a);}for(root = 0;root < n;root++)if(!dfn[root])tarjan(root);for(int i = 1;i <= n;i++)printf("%lld\n",ans[i]);return 0;
}

这篇关于Blockade -tarjan求割点的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/900287

相关文章

【tarjan缩点+小拓展】【POJ-2186】

用刚搞到的模板,去过了一道题 差不多是个模板题 有一群奶牛,奶牛A可以关注B,关注具有传递性,给出奶牛之间的关注关系,问有几只奶牛得到了所有其他奶牛的关注? 互相关注的可以看成一个点,所以直接tarjan算法 + 缩点 新图中,出度为0的点只能有一个,因为如果有两个,这两个新点(原连通分量)就一定是互相没有关注联系的 然后答案就是这个出度为0 的新点(原连通分量)中包含的原来点的个

【hh大神的】Tarjan + 缩点 模板

此模板来自 notonlysuccess 原文链接: http://www.notonlysuccess.com/index.php/tarjan/ 大神就是吊啊。 不多说了,想学tarjan ,资料网上是有一堆的 怎么说。。我现在理解的还不算太透彻,但用模板总行吧 这里只存一下模板 使用时注意清空和存图! (基于个人习惯,稍微有些小改动) #define

Tarjan的脱机最小公共祖先算法详解

Tarjan的脱机最小公共祖先算法详解 一、算法概述二、算法伪代码三、C语言实现四、证明与分析 在解决脱机最小公共祖先(Least Common Ancestors, LCA)问题时,Tarjan算法提供了一种高效的途径。该算法通过一次深度优先搜索(DFS)遍历整棵树,并利用并查集(Union-Find)数据结构来维护节点之间的祖先关系,从而找到任意两个节点的最小公共祖先。

poj 3352 Road Construction(边连通+tarjan+缩点)

http://poj.org/problem?id=3352 题意:简化一下原题题意,意思就是给定一个连通图,问至少要加入几条边使得整个图变成一个边连通图,即图中任意两点都有两条以上的路径(不一定直接相连)。 思路:tarjan算法,设置一个low数组,在建立深搜树的过程中,我们会得到每个节点的low值,对于low值相等的节点在同一个双连通分量中。由于在同一个边连通分量中的点的“地

poj 2942 Knights of the Round Table(双连通分量+tarjan+二分图判定)

http://poj.org/problem?id=2942 题意: 有N个骑士,给出某些骑士之间的仇恨关系,骑士们开会时会围坐在一个圆桌旁。一次会议能够顺利举行,要满足两个条件: 1:任意相互憎恨的两个骑士不能相邻 2:开会人数为大于2的奇数 若某个骑士任何会议都不能参加,那么就必须将他踢出,给出骑士之间的仇恨关系,问最少需要踢出多少个骑士? 思路: 题目要求踢出的人最少,那

poj 2186 Popular Cows(tarjan + 强连通分量 + 缩点)

http://poj.org/problem?id=2186 题意:有n头牛,m个膜拜关系,膜拜关系是不可逆的而且是单向传递的,比如A膜拜B,B膜拜C,那么A也膜拜C,但B不一定膜拜A。最后问有多少头牛满足条件:除了它自己,其他所有的牛都膜拜它。 思路: 问题可以抽象为:给定一个有向图,n个顶点,m条有向边,有多少个顶点满足:其他所有的点都能到达该点。 首先假如图G是一个有向树

poj 3694 Network(tarjan + LCA)

http://poj.org/problem?id=3694 题意:对于一个无向连通图,问加入某条边后,图中有桥的数目。 思路: 根据tarjan算法求出初始图的桥的数目,并用数组bridge标记桥的终点,在tarjan深搜树中求出每个节点的父节点(数组father表示)以及它们的深度,用于以后迭代求LCA。 因为加入某条边后,树中就会存在环,而环中的每条边都不再是桥,这就与求LCA

强连通Tarjan算法入门

A - 迷宫城堡 Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit  Status Description 为了训练小希的方向感,Gardon建立了一座大城堡,里面有N个房间(N<=10000)和M条通道(M<=100000),每个通道都是单向的,就是说若称

强连通分量的tarjan算法

一、数据集形式 其中:1595446(节点个数) 0(起始边) 1(终边) 二、数据集 数据集下载 三、实现代码 // Tarjan.cpp : Defines the entry point for the console application.//#include "stdafx.h"#include "time.h"#include <fstream>#includ

SCC Tarjan算法

int dfs_clock,scc_cnt;int low[maxn],dfn[maxn],sccno[maxn]; //sccno[i]为i所在的SCC编号stack<int>S;vector<int>map[maxn];void tarjan( int u, int fa ){low[u] = dfn[u] = ++dfs_clock;S.push(u);for( int