【LGOJ3469】BLO-Blockade

n个城市由n-1条道路连接
依次输出,如果每个点分别被关闭(无法通过),有多少对点之间无法相互到达

Rumo recently wrote tarjan written a bit
so this is a cut-point of the board title
for each node, if it is not cut point, and that only other point to it, and it can not reach the other point
so the answer is \ (2 * (n -1) \)
If the point is cut, only statistics about the communication block size, calculate the like

Code:

#include<bits/stdc++.h>
#define ll long long
#define N 100005
#define M 500005
using namespace std;

ll n,m,u,v;

struct Edge
{
    int next,to;
}edge[M<<1];
int cnt=0,head[M];

inline void add_edge(int from,int to)
{
    edge[++cnt].next=head[from];
    edge[cnt].to=to;
    head[from]=cnt;
}

template<class T>inline void read(T &res)
{
    char c;T flag=1;
    while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1;res=c-'0';
    while((c=getchar())>='0'&&c<='9')res=res*10+c-'0';res*=flag;
}

int tms=0,low[N],dfn[N];
ll siz[N],ans[N];
bool iscut[N];
void tarjan(int u)
{
    low[u]=dfn[u]=++tms;
    int flag=0;
    ll sum=0;
    siz[u]=1;
    for(register int i=head[u];i;i=edge[i].next)
    {
        int v=edge[i].to;
        if(!dfn[v])
        {
            tarjan(v);
            low[u]=min(low[u],low[v]);
            siz[u]+=siz[v];
            if(dfn[u]<=low[v])
            {
                flag++;
                sum+=siz[v];
                ans[u]+=siz[v]*(n-siz[v]);
                if(u!=1||flag>1) iscut[u]=true;
            }
        }
        else low[u]=min(low[u],dfn[v]);
    }
    if(!iscut[u]) ans[u]=2LL*(n-1);
    else ans[u]+=(ll)(n-sum-1)*(sum+1)+(n-1);
}

int main()
{
    read(n);read(m);
    for(register int i=1;i<=m;++i)
    {
        read(u);read(v);
        add_edge(u,v);
        add_edge(v,u);
    }
    tarjan(1);
//  for(register int i=1;i<=n;++i) cout<<iscut[i]<<" ";cout<<endl; 
    for(register int i=1;i<=n;++i) printf("%lld\n",ans[i]);
    return 0;
}

Guess you like

Origin www.cnblogs.com/tqr06/p/11655955.html