• 【POI2008】BLO


    这道题是在基本的tarjan求割点的算法上进一步加深,加上了计数问题。

    基本思路是显然的,我们必定要跑一遍tarjan求割点,之后我们就要分类讨论。

    若这个点不是割点,那么把他的边去掉之后这个点就与原来的联通块分开了,一共有(n-1)对,因为(x,y),(y,x)算两对,所以答案为n-1<<1

    若这个点是割点,那么把他的边去掉之后这张图就变成了若干部分:这个点自己、在搜索树中这个点的儿子所在的子树、除了以上两部分的联通块。

    因此,我们可以在tarjan的同时求出搜索树中每一棵子树的大小size,由以上总结得到,ans为以上三部分每一部分与剩下的相乘之后再求和即可。

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <algorithm>
     5 using namespace std;
     6 typedef long long ll;
     7 inline int read() {
     8     int ret=0;
     9     int op=1;
    10     char c=getchar();
    11     while(c<'0'||c>'9') {if(c=='-') op=-1; c=getchar();}
    12     while(c<='9'&&c>='0') ret=ret*10+c-'0',c=getchar();
    13     return ret*op;
    14 }
    15 struct node {
    16     int next,to;
    17 }a[500010<<1];
    18 int n,m,head[500010<<1],num,tot;
    19 int dfn[100010],low[100010],size[100010];
    20 ll ans[100010];
    21 int vis[100010];
    22 void add(int from,int to) {
    23     a[++num].next=head[from]; a[num].to=to; head[from]=num;
    24     swap(from,to);
    25     a[++num].next=head[from]; a[num].to=to; head[from]=num;
    26 }
    27 void tarjan(int u) {
    28     dfn[u]=low[u]=++tot;
    29     int pd=0,sum=0;
    30     size[u]=1;
    31     for(int i=head[u];i;i=a[i].next) {
    32         int v=a[i].to;
    33         if(!dfn[v]) {
    34             tarjan(v);
    35             low[u]=min(low[u],low[v]);
    36             size[u]+=size[v];
    37             if(low[v]>=dfn[u]) {
    38                 pd++;
    39                 ans[u]+=(long long)size[v]*(n-size[v]);
    40                 sum+=size[v];
    41                 if(u!=1||pd>1) vis[u]=1;
    42             }
    43         }
    44         else low[u]=min(low[u],dfn[v]);
    45     }
    46     if(vis[u]) ans[u]+=(long long)(n-sum-1)*(sum+1)+n-1;
    47     else ans[u]=(n-1)<<1;
    48 }
    49 int main() {
    50     n=read(); m=read();
    51     for(int i=1;i<=m;i++) {
    52         add(read(),read());
    53     }
    54     tarjan(1);
    55     for(int i=1;i<=n;i++)
    56         printf("%lld
    ",ans[i]);
    57     return 0;
    58 }
    AC Code
  • 相关阅读:
    Android中Acition和Category常量表
    android系统各种音量的获取与设置
    Swift中数组和字典都是值类型
    iOS中的日期和时间
    iOS中的日历
    UILabel的富文本显示选项
    使用NSURLProtocol和NSURLSession拦截UIWebView的HTTP请求(包括ajax请求)
    Error Domain=NSURLErrorDomain Code=-1202,Https服务器证书无效
    iOS计算完整文字高度(适应iOS 10)
    NSUserDefaults存取失败
  • 原文地址:https://www.cnblogs.com/shl-blog/p/10807580.html
Copyright © 2020-2023  润新知