Luogu_P3469 [POI2008]BLO-Blockade tarjan割点
Posted chriskkk
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Luogu_P3469 [POI2008]BLO-Blockade tarjan割点相关的知识,希望对你有一定的参考价值。
Luogu_P3469 [POI2008]BLO-Blockade
### tarjan割点
题目链接
假如(i)不是割点
那么只会(i)分离出去,因为是有顺序的
所以答案是(2*(n-1))
假如(i)是割点
那么设(s)是(i)的儿子,且(s)的(low)值>=(dfn[i])
除去(s)还有一些是到(root)
或是(low)值小于(dfn[i])的点,也就是可以和(root)构成连通块的点
那么答案明显就是
(size[s1]*(n-size[s1])+size[s2]*(n-size[s2])+……+size[st]*(n-size[st])+1*(n-1)+(n-1-sum)*(1+sum))
(sum)是(size)的和
所以在求割点的时候就可以求出(ans)
代码如下:
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxm=500010;
int rt,n,m,head[maxm],tot,dfn[maxm],low[maxm],siz[maxm],num;
bool cut[maxm];
ll ans[maxm];
struct node{
int nxt,to;
#define nxt(x) e[x].nxt
#define to(x) e[x].to
}e[maxm<<1];
inline void add(int from,int to){
to(++tot)=to;nxt(tot)=head[from];head[from]=tot;
}
void tarjan(int x){
low[x]=dfn[x]=++num;siz[x]=1;
int fl=0,sum=0;
for(int i=head[x];i;i=nxt(i)){
int y=to(i);
if(!dfn[y]){
tarjan(y);
siz[x]+=siz[y];
low[x]=min(low[x],low[y]);
if(low[y]>=dfn[x]){
ans[x]+=(ll)siz[y]*(n-siz[y]);
sum+=siz[y];fl++;
if(x!=1 || fl>1) cut[x]=1;
}
}else low[x]=min(low[x],dfn[y]);
}
if(cut[x]) ans[x]+=(ll)(n-sum-1)*(sum+1)+(n-1);
else ans[x]=2*(n-1);
}
int main()
{
scanf("%d%d",&n,&m);
for(int x,y,i=1;i<=m;i++){
scanf("%d%d",&x,&y);
if(x==y) continue;
add(x,y);add(y,x);
}
tarjan(1);
for(int i=1;i<=n;i++)
printf("%lld
",ans[i]);
return 0;
}
以上是关于Luogu_P3469 [POI2008]BLO-Blockade tarjan割点的主要内容,如果未能解决你的问题,请参考以下文章
luogu P3469 [POI2008]BLO-Blockade 割点