博客园 首页 私信博主 显示目录 隐藏目录 管理 动画

Codechef August Challenge 2018 : Lonely Cycles

传送门

几波树形dp就行了。

#include<cstdio>
#include<cstring>
#include<algorithm>
#define MN 5100000
using namespace std;

struct na{int x,y,ne;}b[MN<<1];
int n,m,t,x,y,st[MN],c[MN],s[MN],S[MN],num,l[MN],pdf[MN],nm;
long long ans[MN];
bool bo[MN],W[MN<<1];
inline void add(int x,int y){b[++num].x=x;b[num].y=y;b[num].ne=l[x];l[x]=num;W[num]=0;}
void pre(int x,int f){
    bo[x]=0;pdf[++nm]=x;//printf("%d %d\n",nm,x);
    for (int i=l[x];i;i=b[i].ne)
    if (b[i].y!=f)
    if (bo[b[i].y]) pre(b[i].y,x);
}
void dfs(int x,int p,int f){
    bo[x]=1;
    for (int i=l[x];i;i=b[i].ne)
    if (!W[i]&&b[i].y!=f)
    if (!bo[b[i].y]) st[p]=i,dfs(b[i].y,p+1,x);else{
        W[i]=W[i^1]=1;
        for (int j=p-1;j>=0;j--){
            W[st[j]]=W[st[j]^1]=1;
            if (b[st[j]].x==b[i].y) break;
        }
    }
}
void DFS(int x,int f){
    bo[x]=0;s[x]=1;
    //printf("%d %d\n",x,s[x]);
    for (int i=l[x];i;i=b[i].ne)
    if (b[i].y!=f&&!W[i]) DFS(b[i].y,x),s[x]+=s[b[i].y];
}
void _DFS(int x,int f,int w){
    bo[x]=1;
    for (int i=l[x];i;i=b[i].ne)
    if (b[i].y!=f&&!W[i]) _DFS(b[i].y,x,w+s[x]-s[b[i].y]);
    S[x]=s[x]+w;
}
void work(int x,int f){
    bo[x]=0;
    for (int i=l[x];i;i=b[i].ne)
    if (b[i].y!=f)
    if (!W[i]) work(b[i].y,x),c[x]+=c[b[i].y];else{
        if (bo[b[i].y]) work(b[i].y,x);
        c[x]+=S[b[i].y];
    }
}
void _work(int x,int f,int w1,int w2){
    bo[x]=1;
    for (int i=l[x];i;i=b[i].ne)
    if (b[i].y!=f)
    if (W[i]){
        if (!bo[b[i].y]) _work(b[i].y,x,0,S[x]);
        ans[i>>1]=1LL*S[x]*S[b[i].y];
    }else{
        _work(b[i].y,x,w1+s[x]-s[b[i].y],w2+c[x]-c[b[i].y]);
        ans[i>>1]=1LL*(S[x]-s[b[i].y])*s[b[i].y]+1LL*s[b[i].y]*(w2+c[x]-c[b[i].y])+1LL*(S[x]-s[b[i].y])*c[b[i].y];
    }
}
int main(){
    scanf("%d",&t);
    while(t--){
        scanf("%d%d",&n,&m);
        memset(st,0,(n+10)*4);
        memset(c,0,(n+10)*4);
        memset(s,0,(n+10)*4);
        memset(S,0,(n+10)*4);
        memset(pdf,0,(n+10)*4);
        num=1;nm=0;
        for (int i=1;i<=n;i++) l[i]=0,bo[i]=1;
        for (int i=1;i<=m;i++) scanf("%d%d",&x,&y),add(x,y),add(y,x),ans[i]=0;
        
        for (int i=1;i<=n;i++)
        if (bo[i])
        pre(i,0);
        
        for (int i=1;i<=n;i++)
        if (!bo[pdf[i]])
        dfs(pdf[i],0,0);
        
        for (int i=1;i<=n;i++)
        if (bo[pdf[i]]) DFS(pdf[i],0);
        for (int i=1;i<=n;i++)
        if (!bo[pdf[i]]) _DFS(pdf[i],0,0);
        
        for (int i=1;i<=n;i++)
        if (bo[pdf[i]]) work(pdf[i],0);
        for (int i=1;i<=n;i++)
        if (!bo[pdf[i]]) _work(pdf[i],0,0,0);
        
        for (int i=1;i<=m;i++) printf("%lld\n",ans[i]);
        //printf("%d %d %d %d\n",S[1],S[2],S[3],S[4]);
        //printf("%d %d %d %d %d %d\n",W[2],W[3],W[4],W[5],W[6],W[7]);
    }
}
View Code

 

posted @ 2018-08-17 16:15  swm_sxt  阅读(205)  评论(0编辑  收藏  举报