zoukankan      html  css  js  c++  java
  • [题解]luogu_P3469_BLO(理解tarjan/割点

    给定一张无向图,求每个点被封锁之后有多少个有序点对(x,y)(x!=y,1<=x,y<=n)满足x无法到达y

    首先不是割点答案为2*(n-1),是割点就要考虑删掉割点会分开哪些连通块

    考虑tarjan的过程,核心是对搜索树的处理,如果是割点的话删除掉点x会产生的连通块为x的所有以儿子为根的子树和x子树外的所有部分,每个子树产生的贡献为$size[s1]*(n-size[s1])$,x子树外的贡献为$(size[x])*(n-size[x])$,以及x自己的为$(n-1)$

    #include<bits/stdc++.h>
    #define ll long long
    using namespace std;
    const int maxn=100009;
    const int maxm=500009;
    int n,m,tim,root;
    struct node{
        int v,nxt;
    }e[maxm<<1];
    int head[maxn],cnt=1;
    inline void add(int u,int v){
        e[++cnt].v=v;e[cnt].nxt=head[u];head[u]=cnt;
    }
    int dfn[maxn],low[maxn];bool cut[maxn];
    ll ans[maxn],sz[maxn];
    void tarjan(int x){
        dfn[x]=low[x]=++tim;sz[x]=1;
        int son=0,sum=0;
        for(int i=head[x];i;i=e[i].nxt){
            int y=e[i].v;
            if(!dfn[y]){
                tarjan(y);sz[x]+=sz[y];
                low[x]=min(low[x],low[y]);
                if(low[y]>=dfn[x]){
                    son++;
                    ans[x]+=sz[y]*(n-sz[y]);//每个点只能到当前子树内的点 
                    sum+=sz[y];
                    if(x!=root||son>1)cut[x]=1;
                }
            }
            else low[x]=min(low[x],dfn[y]);
        }
        if(cut[x])ans[x]+=1ll*(n-sum-1)*(sum+1)+(n-1);//x子树外的不能到x子树内的且x不能到其他所有点 
        else ans[x]=2*(n-1);
    }
    int main(){
        scanf("%d%d",&n,&m);
        for(int i=1,u,v;i<=m;i++){
            scanf("%d%d",&u,&v);if(u==v)continue;
            add(u,v);add(v,u);
        }
        for(int i=1;i<=n;i++)
        if(!dfn[i])root=i,tarjan(i);
        for(int i=1;i<=n;i++)printf("%lld
    ",ans[i]);
    }
  • 相关阅读:
    图像处理-06-图像的反色处理
    Egg.js框架
    Node基础
    Node介绍与安装
    线性表结构-数组(散列表与可变长度数组)
    复杂度分析和大O表示法
    Java框架之Struts2(六)
    Java框架之Struts2(五)
    Java框架之Struts2(四)
    Java框架之Struts2(三)
  • 原文地址:https://www.cnblogs.com/superminivan/p/11685938.html
Copyright © 2011-2022 走看看