码迷,mamicode.com
首页 > 其他好文 > 详细

[POI 2008] BLO

时间:2018-07-31 15:12:33      阅读:113      评论:0      收藏:0      [点我收藏+]

标签:www.   add   +=   乘法   printf   否则   div   inline   efi   

[题目链接]

          https://www.lydsy.com/JudgeOnline/problem.php?id=1123

[算法]

         首先,如果一个点不是割点,那么,去掉该点后不连通的有序点对就为 : 2 * (n - 1)

         否则,去掉这个点后,这个图就被分为了 :

         1. 这个点本身

         2. 这个点在搜索树上的一些子树

         3. 除1,2这两部分的节点

         我们可以通过乘法原理算出答案,详见代码

[代码]

       

#include<bits/stdc++.h>
using namespace std;
#define MAXN 100010
#define MAXM 500010

struct edge
{
        int to,nxt;
} e[MAXM << 1];

int i,n,m,x,y,timer,tot;
int size[MAXN],dfn[MAXN],low[MAXN],head[MAXN];
long long ans[MAXN];
bool visited[MAXN],is_cut[MAXN];

inline void addedge(int u,int v)
{
        tot++;
        e[tot] = (edge){v,head[u]};
        head[u] = tot;
}
inline void tarjan(int u)
{
        int i,v,cnt,sum;
        size[u] = 1;
        dfn[u] = low[u] = ++timer;
        visited[u] = true;
        cnt = sum = 0;
        for (i = head[u]; i; i = e[i].nxt)
        {
                v = e[i].to;
                if (!visited[v])
                {
                        tarjan(v);
                        size[u] += size[v];
                        low[u] = min(low[u],low[v]);
                        if (dfn[u] <= low[v])
                        {
                                sum += size[v];
                                cnt++;
                                ans[u] += 1ll * size[v] * (n - size[v]);
                                low[u] = min(low[u],low[v]);
                                if (u != 1 || cnt > 1) is_cut[u] = true;        
                        }
                } else low[u] = min(low[u],dfn[v]);
        }
        if (!is_cut[u]) ans[u] = 2 * (n - 1);
        else ans[u] += 1ll * (n - 1) + 1ll * (n - sum - 1) * (sum + 1);
}

int main() 
{
        
        scanf("%d%d",&n,&m);
        for (i = 1; i <= m; i++)
        {
                scanf("%d%d",&x,&y);
                addedge(x,y);
                addedge(y,x);
        }
        tarjan(1);
        for (i = 1; i <= n; i++) printf("%lld\n",ans[i]);
        
        return 0;
    
}

 

[POI 2008] BLO

标签:www.   add   +=   乘法   printf   否则   div   inline   efi   

原文地址:https://www.cnblogs.com/evenbao/p/9395438.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!