• [bzoj1123] BLO


    1123: [POI2008]BLO

    Time Limit: 10 Sec  Memory Limit: 162 MB
    Submit: 2222  Solved: 1090
    [Submit][Status][Discuss]

    Description

    Byteotia城市有n个 towns m条双向roads. 每条 road 连接 两个不同的 towns ,没有重复的road. 所有towns连通。

    Input

    输入n<=100000 m<=500000及m条边

    Output

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

    Sample Input

    5 5
    1 2
    2 3
    1 3
    3 4
    4 5

    Sample Output

    8
    8
    16
    14
    8

    HINT

    Source

    题意:

    极其简洁啊……

    题解:

    缩完点双后原图会变为一棵树。

    每删掉一个割点,它的子树之间两两不能连接,子树与子树外的点两两不能连接。

    然后惊奇的发现这题的点对要算上被删去的那个点。GG。

    代码:

    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    
    using namespace std;
    #define MAXN 100005
    #define MAXM 500005
    #define INF 0x7fffffff
    #define ll long long
    
    ll hd[MAXN],to[MAXM<<1];
    ll nxt[MAXM<<1],siz[MAXN];
    ll dfn[MAXN],low[MAXN];
    ll N,M,ans[MAXN],cnt,num;
    
    inline ll read(){
        ll x=0,f=1;
        char c=getchar();
        for(;!isdigit(c);c=getchar())
            if(c=='-')
                f=-1;
        for(;isdigit(c);c=getchar())
            x=x*10+c-'0';
        return x*f;
    }
    
    inline void tarjan(ll u){
        dfn[u]=low[u]=++num;
        ll cutnum=0;siz[u]=1;
        for(ll i=hd[u];i;i=nxt[i]){
            ll v=to[i];
            if(dfn[v]) low[u]=min(low[u],dfn[v]);
            else{
                tarjan(v);siz[u]+=siz[v];
                low[u]=min(low[u],low[v]);
                if(dfn[u]<=low[v]){
                    ans[u]+=(cutnum*siz[v]);
                    cutnum+=siz[v];
                }
            }
        }
        ans[u]+=(cutnum*(N-cutnum-1));
        return;    
    }
    
    inline void addedge(ll u,ll v){
        to[++cnt]=v,nxt[cnt]=hd[u];
        hd[u]=cnt;return;    
    }
    
    int main(){
        N=read(),M=read();
        for(ll i=1;i<=M;i++){
            ll u=read(),v=read();
            addedge(u,v),addedge(v,u);
        }
        for(ll i=1;i<=N;i++)
            if(!dfn[i])
                tarjan(i);
        for(ll i=1;i<=N;i++)
            printf("%lld
    ",ans[i]*2+(N-1)*2);
        return 0;
    }
  • 相关阅读:
    深入理解sizeof
    trie树详解
    高精度计算
    编写高效的Android代码
    Android Architecture
    AIDL Android中的远程接口
    性能测试常见术语
    软件与软件测试相关
    注解实现Springmvc+jsp步骤
    非注解实现SpringMvc+JSP (一般用不到 主要用于了解研究底层)
  • 原文地址:https://www.cnblogs.com/YSFAC/p/9914640.html
Copyright © 2020-2023  润新知