[POI2008]BLO-Blockade--Tarjan割点

2023-10-13 12:50

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

Luogu 3469ACwing 365

在这里插入图片描述

题目分析:

  • 对于一个点 u u u,分此点是否为割点进行讨论:

  • u u u不是割点,则将此点删除,其他 n − 1 n-1 n1个点仍联通,则 u u u与其他 n − 1 n-1 n1个点不连通,由于求的是有序点对 ( x , y ) (x,y) (x,y),则 a n s [ u ] = 2 ∗ ( n − 1 ) ans[u]=2*(n-1) ans[u]=2(n1)

  • u u u为割点, u u u t t t v v v,则删除 u u u之后,最多产生 t + 2 t+2 t+2个连通块:
    u u u自己为一个连通块
    t t t v v v各自为一个连通块
    其他的节点构成一个连通块

  • 对于 u u u v v v,若 d f n [ u ] &lt; = l o w [ v ] , s u m = ∑ s i z e [ v ] dfn[u]&lt;=low[v],sum=\sum{size[v]} dfn[u]<=low[v],sum=size[v]
    a n s [ u ] = s i z e [ v 1 ] ∗ ( n − s i z e [ v 1 ] ) + s i z e [ v 2 ] ∗ ( n − s i z e [ v 2 ] ) + . . . . . . + s i z e [ v t ] ∗ ( n − s i z e [ v t ] ) + ( n − s u m − 1 ) ∗ ( s u m + 1 ) ans[u]=size[v_1]*(n-size[v_1])+size[v_2]*(n-size[v_2])+......+size[v_t]*(n-size[v_t])+(n-sum-1)*(sum+1) ans[u]=size[v1](nsize[v1])+size[v2](nsize[v2])+......+size[vt](nsize[vt])+(nsum1)(sum+1)

Code:

#include <bits/stdc++.h>
using namespace std;
#define maxn 100010
#define maxm 500010int n,m,size=0,head[maxn],f[maxn],cnt=0,dfn[maxn],low[maxn];
long long ans[maxn];
bool co[maxn];
struct edge {int v,nxt;
}e[maxm<<1];inline void init_() {freopen("a.txt","r",stdin);
}inline int read_() {int x=0,f=1;char c=getchar();while(c<'0'||c>'9') {if(c=='-') f=-1;c=getchar();}while(c>='0'&&c<='9') {x=(x<<1)+(x<<3)+c-'0';c=getchar();}return x*f;
}inline void add_(int u,int v) {e[++size].v=v;e[size].nxt=head[u];head[u]=size;
}inline void clean_() {memset(co,false,sizeof(co));memset(head,-1,sizeof(head));memset(dfn,0,sizeof(dfn));
}void Tarjan_(int u) {dfn[u]=low[u]=++cnt;f[u]=1;ans[u]=0;int flag=0,sum=0;for(int i=head[u];~i;i=e[i].nxt) {int v=e[i].v;if(!dfn[v]) {Tarjan_(v);low[u]=min(low[u],low[v]);f[u]+=f[v];if(dfn[u]<=low[v]) {++flag;ans[u]+=(long long) f[v]*( (long long) n-f[v] );sum+=f[v];if(u!=1||flag>1) co[u]=true;}}else low[u]=min(low[u],dfn[v]);}if(co[u]) {ans[u]+=(long long) n-1;ans[u]+=(long long) ( (long long) n-sum-1 ) * ( (long long) sum+1 );}else {ans[u]=(long long) 2 * ( (long long) n-1 );}
}void readda_() {n=read_();m=read_();clean_();int x,y;for(int i=1;i<=m;++i) {x=read_();y=read_();if(x==y) continue;add_(x,y);add_(y,x);}Tarjan_(1);for(int i=1;i<=n;++i) printf("%lld\n",ans[i]);
}int main() {init_();readda_();return 0;
}

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



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

相关文章

图的割点、割线问题

图的割点问题 邻接矩阵表示图 package com.hyl.algorithm.other;import java.util.Arrays;import com.hyl.algorithm.search.base.SearchIntf;import com.hyl.algorithm.search.base.SearchIntfFactory;/*** 寻找图的割点* <p>** @aut

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

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

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

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

HIHO #1183 : 连通性一·割边与割点

题目链接 使用Tarjan算法计算无向图的割点和桥,提示讲解的也很清晰 需要注意的是,某一个割点可能会被多次计算,所以一般是先记录然后最后统一输出 1)按照题目的伪代码直接实现 2)稍微优化一下的,省一些空间 #include<bits/stdc++.h>using namespace std;#define cl(a,b) memset(a,b,sizeof(a))#define

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

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

P3388 【模板】割点(割顶)

~~~~~      P3388 【模板】割点(割顶) ~~~~~      总题单链接 割点的定义 ~~~~~      在一张无向图中,若删除一个点后连通块的数量会增加,那这个点就是割点。 怎么找割点 ~~~~~      按 d f s dfs dfs序 访问图上的每个点,每个点只访问一遍。 ~~~~~      先来看看时间戳的定义,若一个点的时间戳为 x x x,那

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