求助!!!这个LCT太恶心了。

P4383 [八省联考 2018] 林克卡特树

爱喝敌敌畏 @ 2019-11-24 15:13:23

#include<cstdio>
#include<cstring>
#include<algorithm>
#define  N  310000
#define  NN  610000
using  namespace  std;
typedef  long  long  LL;
template  <class  T>
inline  T  mymin(T  x,T  y){return  x<y?x:y;}
template  <class  T>
inline  T  mymax(T  x,T  y){return  x>y?x:y;}
//DP数组 
struct  node
{
    LL  sh;//表示分的段数,1,2不算一段 
    LL  x;//表示的是保留一条边减去保留两条然后加上到父亲的边权。 
    node(LL  xx=0,LL  yy=0){x=xx;sh=yy;}
}f[N][3];
inline  bool  operator<(node  x,node  y){return  x.x!=y.x?(x.x<y.x):(x.sh<y.sh);}
inline  bool  operator>(node  x,node  y){return  x.x!=y.x?(x.x>y.x):(x.sh>y.sh);}
inline  node  operator+(node  x,node  y){return  node(x.x+y.x,x.sh+y.sh);}
struct  bian
{
    LL  y,next;
    LL  c;
}a[NN];LL  len=1,last[N];
void  ins(LL  x,LL  y,LL  c){len++;a[len].y=y;a[len].c=c;a[len].next=last[x];last[x]=len;}
LL  fu/*表示每次断边的附加权值*/,top;
bool  v[N];//是否有被查到 
node  an;
void  dfs(LL  x,LL  fa)//处理出最简单的DP 
{
    if(x==6)
    {
        x++;
        x--;
    }
    f[x][0]=f[x][2]=node(0,0);f[x][1]=node((LL)-9999999999999999,0/*自己自成一段*/);
    for(LL  k=last[x];k;k=a[k].next)
    {
        LL  y=a[k].y;
        if(y!=fa)dfs(y,x);//处理出子树信息 
    }
    for(LL  k=last[x];k;k=a[k].next)
    {
        LL  y=a[k].y;
        if(y!=fa)
        {
            node  no1=mymax(f[y][0],f[y][1]);no1.x+=a[k].c;//使用这条边的最大值 
            node  no2=mymax(f[y][1],f[y][2]);no2=mymax(node(no2.x+fu,no2.sh+1)/*断边*/,f[y][0]/*不断边,也不使用*/);//表示不使用这条边,割掉,或者直接不用 
            //询问其能不能多添加一条边 
            f[x][2]=mymax(f[x][2]+no2,f[x][1]+no1);
            f[x][1]=mymax(f[x][1]+no2,f[x][0]+no1/*表示使用这条边*/); 
            f[x][0]=f[x][0]+no2;//表示使用其中的0条边。 
        }
    }
}
LL  n,m;//表示点数和边数。 
bool  check()
{
    dfs(1,0);//表示遍历1所在的子树。
    f[1][1].sh++;f[1][2].sh++;
    f[1][1].x+=fu;f[1][2].x+=fu;
    an=mymax(f[1][0],mymax(f[1][1],f[1][2]));
    return  an.sh>=m;
}
int  main()
{
    freopen("1.in","r",stdin);
    freopen("1.out","w",stdout);
    scanf("%lld%lld",&n,&m);m++;
    for(LL  i=1;i<n;i++)
    {
        LL  x,y;LL  c;scanf("%lld%lld%lld",&x,&y,&c);
        ins(x,y,c);ins(y,x,c);
    }
    LL  l=-1e6,r=1e6,zans=0;
    while(l<=r)
    {
        fu=(l+r)/2;
        if(check())
        {
            zans=an.x-(LL)m*fu;
            r=fu-1;
        }
        else  l=fu+1;
    }
    printf("%lld\n",zans);
    return  0;
}

前面的错了,后面的对了,40分,对拍都拍不出来


by 小鲍bob @ 2019-11-24 15:21:11

您不就是发帖说想AK IOI的那个人吗


by Lates @ 2019-11-24 15:36:43

@小鲍bob 他被jc了


by ducati @ 2021-03-16 20:11:34

这题与 LCT 有什么关系吗/yiw


by ADay @ 2021-08-09 13:48:37

@ducati 林克卡特树不就是link-cut tree吗


|