【圆方树+树形dp】P4630 [APIO2018] Duathlon 铁人两项

题面:https://www.luogu.com.cn/problem/P4630

 

先用tarjan把原图建成圆方树

圆点赋值-1,方点赋值环的大小

对于每个点对,方案数为圆方树上的路径权值

然后利用树形dp处理每个点对的贡献

计算子树根节点经过的次数乘以2即可

 

代码

#include<bits/stdc++.h>
using namespace std;
const int maxn=2e5+5;
int n,m,head[maxn],size[maxn],cnt,tot,tott,v[maxn],h[maxn<<1],low[maxn],dfn[maxn],s[maxn],times,top;
struct edge
{
    int to,nxt;
}e[maxn<<1],G[maxn<<3];
void add(int x,int y)
{
    e[++cnt].nxt=head[x];
    e[cnt].to=y;
    head[x]=cnt;
}
void addd(int x,int y)
{
    G[++tott].nxt=h[x];
    G[tott].to=y;
    h[x]=tott;
}
void tarjan(int x)
{
    low[x]=dfn[x]=++times;
    s[++top]=x;
    size[x]=1;
    for(int i=head[x];i;i=e[i].nxt)
    {
        int to=e[i].to;
        if(!dfn[to])
        {
            tarjan(to);
            low[x]=min(low[x],low[to]);
            if(low[to]==dfn[x])
            {
                int xx=0,num=1; tot++;
                do
                {
                    xx=s[top--];
                    ++num;
                    addd(tot,xx); addd(xx,tot);    
                    size[tot]+=size[xx];
                }while(xx!=to);
                v[tot]=num;
                size[x]+=size[tot];
                addd(x,tot); addd(tot,x);
            }
        }
        else low[x]=min(low[x],dfn[to]);
    }
}
long long ans=0;
void dfs(int root,int u,int fa)
{
    int tmp=(u<=n);
    ans+=2LL*size[u]*(size[root]-size[u])*v[u];
    for(int i=h[u];i;i=G[i].nxt)
    {
        int to=G[i].to;
        if(to==fa) continue;
        ans+=2LL*tmp*size[to]*v[u];
        tmp+=size[to];
        dfs(root,to,u);
    }
}
int main()
{
    freopen("a.in","r",stdin);
    freopen("a.out","w",stdout);
    scanf("%d%d",&n,&m);
    int x,y; tot=n;
    for(int i=1;i<=n;i++) v[i]=-1;
    for(int i=1;i<=m;i++)
    {
        scanf("%d%d",&x,&y);
        add(x,y); add(y,x);
    }
    for(int i=1;i<=n;i++)
        if(!dfn[i])
        {
            tarjan(i);
            dfs(i,i,0);
        }
    printf("%lld",ans);
    return 0;
}

 

posted @ 2020-11-28 22:14  andyc_03  阅读(88)  评论(0编辑  收藏  举报