• loj10104 [POI 2008]Blockade


    传送门

    分析

    我们知道对于一个割点,我们如果去掉它就会使原来的图被分为若干块,则这是我们将所有块包含的点的个数两两相乘即可,而如果不是割点则对于图的连通性没有影响。注意在最后要加上2*(n-1)表示去掉的那个点对答案产生的贡献。

    代码

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<algorithm>
    #include<cctype>
    #include<cmath>
    #include<cstdlib>
    #include<queue>
    #include<ctime>
    #include<vector>
    #include<set>
    #include<map>
    #include<stack>
    using namespace std;
    long long dfn[100010],low[100010],cnt,sum,siz[100010];
    long long ans[100010],n,m;
    vector<long long>v[100010];
    inline void tarjan(long long x,long long la){
          siz[x]=1;
          dfn[x]=low[x]=++cnt;
          long long son=0,tot=0;
          for(long long i=0;i<v[x].size();i++)
            if(v[x][i]!=la){
              if(!dfn[v[x][i]]){
                  son++;
                  tarjan(v[x][i],x);
                siz[x]+=siz[v[x][i]];
                  low[x]=min(low[x],low[v[x][i]]);
                  if(dfn[x]<=low[v[x][i]]){
                    ans[x]+=siz[v[x][i]]*tot;
                    tot+=siz[v[x][i]];
                  }
              }else low[x]=min(low[x],dfn[v[x][i]]);
            }
          ans[x]+=tot*(n-tot-1);
          if(son==1&&!la)ans[x]=0;
    }
    int main(){
          long long i,j,k;
          scanf("%lld%lld",&n,&m);
          for(i=1;i<=m;i++){
              long long x,y;
              scanf("%lld%lld",&x,&y);
              v[x].push_back(y);
              v[y].push_back(x);
          }
          for(i=1;i<=n;i++)
            if(!dfn[i])tarjan(i,0);
          for(i=1;i<=n;i++)printf("%lld
    ",(ans[i]+n-1)*2);
          return 0;
    }
  • 相关阅读:
    对于作用域和闭包的理解
    响应式开发学习(3)——图片优化
    响应式开发(2)
    响应式开发(1)
    数据结构
    进阶题目
    集合
    数组
    内存相关
    线程
  • 原文地址:https://www.cnblogs.com/yzxverygood/p/9531698.html
Copyright © 2020-2023  润新知