19CSP-S eleven three training exam - Homing gods

Chain split tree T2

( Http://zhengruioi.com/problem/1120 )
Gu Gu ~ ~ ~ Gu

sol:

This problem is a classic tree root DP change. Because it is considered chain split tree, the node is noninteracting different depths. DP that would even out as far as the edges of the current node, the number can be covered up.
The main change is to review the root method. First, to make \ (1 \) where as the root, the process and the edges are covered most often multiple times situation \ (son1 [x] \) and \ (son2 [X] \) . Consider the choice of root depth gradually increases each time they change it answers, and then update \ (son1 [x] \) and \ (son2 [x] \) can be.
Remember before exiting the state must come back before.

code:

#include <bits/stdc++.h>
#define ll long long
using namespace std;
inline int read(){
    int x=0;char c=getchar();
    while(c<'0'||c>'9') c=getchar();
    while(c>='0'&&c<='9') x=(x<<3)+(x<<1)+c-'0',c=getchar();
    return x;
}
const int N=100005;
int n,m,st[N][20],dep[N],val[N],son1[N],son2[N],ans,tmp;
int ver[N<<1],nxt[N<<1],head[N],tot,len,num;
inline void add(int x,int y){ver[++tot]=y;nxt[tot]=head[x];head[x]=tot;}
void dfs1(int x,int la){
    st[x][0]=la;dep[x]=dep[la]+1;
    for(int i=1;(1<<i)<dep[x];i++)
        st[x][i]=st[st[x][i-1]][i-1];
    for(int i=head[x];i;i=nxt[i]){
        int y=ver[i];
        if(y==la) continue;
        dfs1(y,x);
    }
}
inline int getlca(int x,int y){
    if(dep[x]<dep[y]) swap(x,y);
    for(int i=19;i>=0;i--){
        if((1<<i)>dep[x]-dep[y]) continue;
        x=st[x][i];len+=(1<<i);
    }
    if(x==y) return x;
    for(int i=19;i>=0;i--){
        if(st[x][i]==st[y][i]) continue;
        x=st[x][i];y=st[y][i];
        len+=(1<<i+1);
    }
    len+=2;return st[x][0];
}
void dfs2(int x,int la){
    for(int i=head[x];i;i=nxt[i]){
        int y=ver[i];
        if(y==la) continue;
        dfs2(y,x);
        val[x]+=val[y];
    }
    if(son1[la]<val[x]) son2[la]=son1[la],son1[la]=val[x];
    else if(son2[la]<val[x]) son2[la]=val[x];
    num+=son1[x];
}
void dfs3(int x,int la){
    for(int i=head[x];i;i=nxt[i]){
        int y=ver[i];
        if(y==la) continue;
        int tmp1=son1[y],tmp2=son2[y],tmp3=son1[x],tmp4=son2[x];
            //这里一定要把这些信息备份一下,供以后退回原来状态时使用
        if(val[y]==tmp3) num=num-tmp3+tmp4;
        if(val[y]>tmp1) num=num-tmp1+val[y],son2[y]=son1[y],son1[y]=val[y];
        else if(val[y]>tmp2) son2[y]=val[y];
        ans=max(ans,num);
        dfs3(y,x);
        if(val[y]==tmp3) num=num+tmp3-tmp4;
        if(val[y]>tmp1) num=num+tmp1-val[y],son2[y]=tmp2,son1[y]=tmp1;
        else if(val[y]>tmp2) son2[y]=tmp2;
    }
    
}
int main(){
    n=read();m=read();
    for(int i=1;i<n;i++){
        int x=read(),y=read();
        add(x,y);add(y,x);
    }
    dfs1(1,0);
    for(int i=1;i<=m;i++){
        int x=read(),y=read();
        int lca=getlca(x,y);
        val[x]++;val[y]++;
        val[lca]-=2;
    }
    dfs2(1,0);ans=num;
    dfs3(1,0);
    printf("%d\n",len-ans);
    return 0;
}

Guess you like

Origin www.cnblogs.com/zxynothing/p/11700783.html