为什么用oiwiki上的方法求重心过不了?
  • 板块P4178 Tree
  • 楼主Bluebird_
  • 当前回复4
  • 已保存回复4
  • 发布时间2023/2/3 15:35
  • 上次更新2023/10/24 01:53:19
查看原帖
为什么用oiwiki上的方法求重心过不了?
213535
Bluebird_楼主2023/2/3 15:35

这是我的getroot函数,用oiwiki上的求法只能10pts 无法理解T_T

void getroot(int u,int fa)
{
    sz[u]=1;//int mx=0;
    mx[u]=0;
    for(int i=head[u];i;i=nxt[i])
    {
        int v=to[i];
        if(v!=fa&&!vis[v])getroot(v,u),sz[u]+=sz[v],mx[u]=max(mx[u],sz[v]);
    }
    mx[u]=max(mx[u],S-sz[u]);
    if(mx[u]<=mx[Root])Root=u; //可AC求法
    // if(mx[u]<=S/2)Root=u;   //OIWIKI上的求法
}
#include<iostream>
#include<algorithm>
#define int long long
using namespace std;
inline int rd()
{
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9')f=ch=='-'?-1:1,ch=getchar();
    while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
    return x*f;
}
inline void wr(int x)
{
    if(x<0){putchar('-');wr(-x);return;}
    if(x>9)wr(x/10);
    putchar(char(x%10+'0'));
    return;
}
const int N=4e4+100;
int n,to[N<<1],nxt[N<<1],head[N],val[N<<1],cnt;
int k,sz[N],mxsz,Root,vis[N],dep[N],d[N],S,ans,mx[N];
void add(int u,int v,int w)
{
    to[++cnt]=v;nxt[cnt]=head[u];head[u]=cnt;val[cnt]=w;
}
void getroot(int u,int fa)
{
    sz[u]=1;//int mx=0;
    mx[u]=0;
    for(int i=head[u];i;i=nxt[i])
    {
        int v=to[i];
        if(v!=fa&&!vis[v])getroot(v,u),sz[u]+=sz[v],mx[u]=max(mx[u],sz[v]);
    }
    mx[u]=max(mx[u],S-sz[u]);
    if(mx[u]<=mx[Root])Root=u; //可行求法
    // if(mx[u]<=S/2)Root=u;   //OIWIKI上的求法
}
void gtdp(int u,int fa)
{
    dep[++dep[0]]=d[u];
    for(int i=head[u];i;i=nxt[i])
    {
        int v=to[i],w=val[i];
        if(vis[v]||v==fa)continue;
        d[v]=d[u]+w;
        gtdp(v,u);
    }
}
int gt(int u,int dis)
{
    d[u]=dis;dep[0]=0;
    gtdp(u,-1);
    int l=1,r=dep[0],ret=0;
    sort(dep+1,dep+dep[0]+1);
    while (l<r)
        if(dep[l]+dep[r]<=k)ret+=r-l,++l;
        else --r;
    return ret;
}
void go(int u)
{
    vis[u]=1;
    ans+=gt(u,0);
    for(int i=head[u];i;i=nxt[i])
    {
        int v=to[i],w=val[i];
        if(vis[v])continue;
        ans-=gt(v,w);
        Root=0;S=sz[v];
        getroot(v,u);
        go(Root);
    }
}
signed main()
{
    // freopen("A.in","r",stdin);
    n=rd();
    mx[0]=0x7fffffff;
    for(int i=1;i<n;++i)
    {
        int u=rd(),v=rd(),w=rd();
        add(u,v,w);
        add(v,u,w);
    }
    k=rd();
    S=n;
    getroot(1,-1);
    go(Root);
    wr(ans);putchar('\n');
    return 0;
}
/*
5 
1 2 3
1 3 1
1 4 2
3 5 1
4

7
1 6 999 
6 3 25 
7 5 5
4 1 30
2 4 10 
4 7 2 
15

7 15
1 6 999 
6 3 25 
7 5 5
4 1 30
2 4 10 
4 7 2 
*/
2023/2/3 15:35
加载中...