zoukankan      html  css  js  c++  java
  • bzoj1123 [POI2008]BLO——求割点子树相乘

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

    思路倒是有的,不就是个乘法原理吗,可是不会写...代码能力...

    写了一堆麻麻烦烦乱七八糟的东西写不下去了,去看TJ...

    原来是在 tarjan 里面就顺便算出来了啊!真是精妙!这就是构建出了一个 dfs 搜索树了呢;

    码力还需多多提升...

    代码如下:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    typedef long long ll;
    int const maxn=1e5+5,maxm=5e5+5;
    int n,m,hd[maxn],ct,siz[maxn],dfn[maxn],low[maxn],tim;
    ll ans[maxn];
    struct N{
        int to,nxt;
        N(int t=0,int n=0):to(t),nxt(n) {}
    }ed[maxm<<1],edge[maxm<<1];
    void add(int x,int y){ed[++ct]=N(y,hd[x]); hd[x]=ct;}
    void tarjan(int x,int f)
    {
        dfn[x]=low[x]=++tim; 
        ll t=0; siz[x]=1;//注意t是ll,否则下面算给ans时爆int 
        for(int i=hd[x],u;i;i=ed[i].nxt)
        {
            if((u=ed[i].to)==f)continue;
            if(!dfn[u])
            {
                tarjan(u,x); siz[x]+=siz[u];
                low[x]=min(low[x],low[u]);
                if(low[u]>=dfn[x])ans[x]+=siz[u]*t,t+=siz[u];//t是割点的子树大小 
            }
            else low[x]=min(low[x],dfn[u]);
        }
        ans[x]+=t*(n-t-1);
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=1,x,y;i<=m;i++)
        {
            scanf("%d%d",&x,&y);
            add(x,y); add(y,x);
        }
        tarjan(1,0);
        for(int i=1;i<=n;i++)printf("%lld
    ",(ans[i]+n-1)*2);
        return 0;
    }
  • 相关阅读:
    爬虫入门(五)
    爬虫入门(四)
    爬虫入门(三)
    爬虫入门(二)
    爬虫入门(一)
    openpyxl的简单使用
    ansible(三)
    ansible(二)
    ansible(一)
    CF Global Round 10-F
  • 原文地址:https://www.cnblogs.com/Zinn/p/9291482.html
Copyright © 2011-2022 走看看