zoukankan      html  css  js  c++  java
  • [POI 2008] BLO

    [题目链接]

              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
    ",ans[i]);
            
            return 0;
        
    }
  • 相关阅读:
    爬取校园新闻首页的新闻的详情,使用正则表达式,函数抽离
    网络爬虫基础练习
    Hadoop综合大作业
    hive基本操作与应用
    用mapreduce 处理气象数据集
    熟悉常用的HBase操作
    爬虫大作业
    熟悉常用的HDFS操作
    数据结构化与保存
    获取全部校园新闻
  • 原文地址:https://www.cnblogs.com/evenbao/p/9395438.html
Copyright © 2011-2022 走看看