• BZOJ 1123: [POI2008]BLO


    1123: [POI2008]BLO

    Time Limit: 10 Sec  Memory Limit: 162 MB
    Submit: 1030  Solved: 440
    [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

     
    [Submit][Status][Discuss]

    分析

    如果一个点不是割点,那么删去后不会对其他点之间的连通性造成影响;如果是一个割点,影响只和其连接的几个块的大小有关。因此Tarjan求割点的同时注意维护子树大小即可。

    代码

     1 #include <cmath>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <cstdlib>
     5 #include <iostream>
     6 #include <algorithm>
     7 
     8 using namespace std;
     9 
    10 #define N 5000000
    11 #define LL long long
    12 
    13 int n, m; LL ans[N];
    14 
    15 int hd[N], to[N], nt[N], tot;
    16 
    17 int dfn[N], low[N], tim;
    18 
    19 int tarjan(int u, int f)
    20 {   
    21     dfn[u] = low[u] = ++tim; ans[u] = (n - 1) << 1;
    22     
    23     int cnt = 0, siz; LL sum = 0, tmp = 0;
    24     
    25     for (int i = hd[u]; ~i; i = nt[i])if (f != to[i])
    26     {
    27         if (!dfn[to[i]])
    28         {
    29             siz = tarjan(to[i], u);
    30             low[u] = min(low[u], low[to[i]]);
    31             if (low[to[i]] >= dfn[u])
    32                 ans[u] += 2LL * siz * sum, sum += siz;
    33             else
    34                 tmp += siz;
    35         }
    36         else
    37             low[u] = min(low[u], dfn[to[i]]);
    38     }
    39     
    40     ans[u] += 2LL * (n - (sum + 1)) * sum;
    41     
    42     return sum + tmp + 1;
    43 }
    44 
    45 signed main(void)
    46 {
    47     scanf("%d%d", &n, &m);
    48     
    49     memset(hd, -1, sizeof(hd)), tot = 0;
    50     
    51     for (int i = 1; i <= m; ++i)
    52     {
    53         int x, y; scanf("%d%d", &x, &y);
    54         
    55         nt[tot] = hd[x]; to[tot] = y; hd[x] = tot++;
    56         nt[tot] = hd[y]; to[tot] = x; hd[y] = tot++;
    57     }
    58     
    59     memset(dfn, 0, sizeof(dfn)); tim = 0; tarjan(1, -1);
    60     
    61     for (int i = 1; i <= n; ++i)
    62         printf("%lld
    ", ans[i]);
    63 }
    BZOJ_1123.cpp
     1 #include <cstdio>
     2 
     3 template <class T>
     4 inline T min(const T &a, const T &b)
     5 {
     6     return a < b ? a : b;
     7 }
     8 
     9 typedef long long lnt;
    10 
    11 const int mxn = 100005;
    12 const int mxm = 1000005;
    13 
    14 int n, m;
    15 
    16 int hd[mxn];
    17 int to[mxm];
    18 int nt[mxm];
    19 
    20 int dfn[mxn];
    21 int low[mxn];
    22 
    23 lnt ans[mxn];
    24 
    25 lnt tarjan(int u, int f)
    26 {
    27     static int tim = 0;
    28 
    29     ans[u] = (n - 1) << 1;
    30     dfn[u] = low[u] = ++tim;
    31 
    32     lnt siz, sum = 0, tmp = 0;
    33 
    34     for (int i = hd[u], v; i; i = nt[i])
    35         if ((v = to[i]) != f)
    36         {
    37             if (!dfn[v])
    38             {
    39                 siz = tarjan(v, u);
    40 
    41                 low[u] = min(low[u], low[v]);
    42 
    43                 if (low[v] >= dfn[u])
    44                     ans[u] += 2LL * sum * siz, sum += siz;
    45                 else
    46                     tmp += siz;
    47             }
    48             else
    49                 low[u] = min(low[u], dfn[v]);
    50         }
    51 
    52     ans[u] += 2LL * (n - sum - 1) * sum;
    53 
    54     return sum + tmp + 1;
    55 }
    56 
    57 signed main(void)
    58 {
    59     scanf("%d%d", &n, &m);
    60 
    61     for (int i = 0; i < m; ++i)
    62     {
    63         static int x, y, tot;
    64 
    65         scanf("%d%d", &x, &y);
    66 
    67         nt[++tot] = hd[x], to[tot] = y, hd[x] = tot;
    68         nt[++tot] = hd[y], to[tot] = x, hd[y] = tot;
    69     }
    70 
    71     tarjan(1, 0);
    72 
    73     for (int i = 1; i <= n; ++i)
    74         printf("%lld
    ", ans[i]);
    75 }

    @Author: YouSiki

  • 相关阅读:
    浅谈Java中的equals和==与hashCode
    数组操作
    python-类
    javascript操控浏览器
    javascript_获取浏览器属性
    javascript_data
    python3_phantomJS_test
    python检测字符串的字母
    python百分比数比较大小
    selenium加载时间过长
  • 原文地址:https://www.cnblogs.com/yousiki/p/6091587.html
Copyright © 2020-2023  润新知