bzoj1131: [POI2008]Sta

二次扫描+换根

有点困思路不清晰啊

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long LL;

struct node
{
    int x,y,next;
}a[2100000];int len,last[1100000];
void ins(int x,int y)
{
    len++;
    a[len].x=x;a[len].y=y;
    a[len].next=last[x];last[x]=len;
}
int fa[1100000],dep[1100000],tot[1100000];
LL sum[1100000];
void dfs(int x)
{
    tot[x]=1;
    for(int k=last[x];k;k=a[k].next)
    {
        if(a[k].y!=fa[x])
        {
            fa[a[k].y]=x;
            dep[a[k].y]=dep[x]+1;
            dfs(a[k].y);
            sum[x]+=sum[a[k].y]+tot[a[k].y];
            tot[x]+=tot[a[k].y];
        }
    }
}
LL mmax,now,cnt;int id;
void changert(int x)
{
    if(now+sum[x]>mmax)
        mmax=now+sum[x],id=x;
    else if(now+sum[x]==mmax)id=min(id,x);
        
    for(int k=last[x];k;k=a[k].next)
    {
        if(a[k].y!=fa[x])
        {
            cnt+=tot[x]-tot[a[k].y];
            now+=(sum[x]-(sum[a[k].y]+tot[a[k].y]))+cnt;
            changert(a[k].y);
            now-=(sum[x]-(sum[a[k].y]+tot[a[k].y]))+cnt;
            cnt-=tot[x]-tot[a[k].y];
        }
    }
}
int main()
{
    freopen("a.in","r",stdin);
    freopen("a.out","w",stdout);
    int n,x,y;
    scanf("%d",&n);
    len=0;memset(last,0,sizeof(last));
    for(int i=1;i<n;i++)
    {
        scanf("%d%d",&x,&y);
        ins(x,y),ins(y,x);
    }
    fa[1]=0;dep[1]=1;dfs(1);
    mmax=0,id=(1<<30),now=0,cnt=0;
    changert(1);
    printf("%d\n",id);
    return 0;
}

 

posted @ 2018-10-30 16:07  AKCqhzdy  阅读(109)  评论(0编辑  收藏  举报