zoukankan      html  css  js  c++  java
  • 圆方树

    圆方树是Tarjan发明,ImmortalCO引入CNOI界的一种处理无向图/仙人掌的利器

    具体地,圆方树可以简便地把一个无向图变成树/仙人掌

    做法就是Tarjan搜点双的时候,对于每个点双我们建一个方点向这个点双里的点连边,割点向相邻的方点连边

    然后就有很多很神仙的性质/应用

    但对我来说就是一种优秀的点双缩点写法吧..

    代码:APIO2018 铁人两项

    #include<bits/stdc++.h>
    #define LL long long 
    using namespace std;
    inline int read()
    {
        int now = 0,fa = 1;char ch = getchar();
        for(;!isdigit(ch);ch = getchar())if(ch == '-') fa = -fa;
        for(;isdigit(ch);ch = getchar())now = 10 * now + ch - '0';
        return now * fa;
    }
    const int maxn = 100010;
    int n,m;
    struct Graph
    {
        int first[maxn],to[maxn << 1],nx[maxn],cnt;
        inline void add(int u,int v)
        {
            to[++cnt] = v;
            nx[cnt] = first[u];
            first[u] = cnt;
        }
    }G,Tree;
    LL val[maxn],ans;int tot;
    LL sum = 0;
    int dfn[maxn],low[maxn],stk[maxn],ins[maxn],top,DFN,isc[maxn];
    inline void Tarjan(int u,int fa)
    {
        sum++; 
        dfn[u] = low[u] = ++DFN;stk[++top] = u;ins[u] = 1;
        val[u] = -1;
        for(int i=G.first[u];i;i=G.nx[i])
        {
            int targ = G.to[i];
            if(targ == fa)continue;
            if(!ins[targ])
            {
                Tarjan(targ,u);
                low[u] = min(low[u],low[targ]);
                if(low[targ] >= dfn[u])
                {
                    tot++;
                    val[tot] = 1;
                    Tree.add(u,tot);
                    do
                    {
                        Tree.add(tot,stk[top]);
                        val[tot]++;
                    }while(targ != stk[top--]);
                }
            }
            else low[u] = min(low[u],dfn[targ]);
        }
    }
    inline int dfs(int x,int type)
    {
        LL size = type;
        for(int i=Tree.first[x];i;i=Tree.nx[i])
        {
            LL now = dfs(Tree.to[i],!type);
            ans += now * (sum - now) * val[x];
            size += now;
        }
        ans += (sum - size) * size * val[x];
        if(type) ans += (sum - 1ll) * val[x];
        return size;
    }
    int main()
    {
        tot = n = read(),m = read();
        for(int i=1;i<=m;i++)
        {
            int u = read(),v = read();
            G.add(u,v);G.add(v,u);
        }
        for(int i=1;i<=n;i++)
            if(!ins[i])
            {
                sum = 0;
                Tarjan(i,0);
                dfs(i,1);
            }
        printf("%lld",ans);
    }
    View Code
  • 相关阅读:
    JS语言中的JSON.parse()和JSON.stringify()
    Django中 @login_required用法简介
    Django model中的save后的return
    windows下gethostbyname 调用失败
    学习打造自己的DEBUG_NEW
    关于new/delete、malloc/free的内存泄漏检测
    C++连接mysql的两种方式(ADO连接和mysql api连接)
    windows下Redis编译安装
    mysql之字符编码问题
    mysql错误用法insert into where
  • 原文地址:https://www.cnblogs.com/Kong-Ruo/p/9709089.html
Copyright © 2011-2022 走看看