$ Noip2018 / Luogu5021 $-half track construction + tree

$ Luogu $

 

$Sol$

Always I thought it was only after each point once never thought that each side can only go through once .... $ $

In fact, this part of the first question sub $ 55 $ points really well written ah, namely chain, diameter and number of chrysanthemum map, not explained in detail here.

So that the construction of the $ m $ track the length of the track in a minimum length of maximum With these words apparently would think half now is to consider how to judge.

Arbitrarily selected as the root node contribution is noted that a circuit composed of fact only two, one is a simple chain from shallow to deep, the other is from dark to light and then deep Such double fold chain consider the processing from deep to shallow junction for each node, the node upload handle a chain length plus the edge weight is added between the parent and child $ mutiset $. has been first found value greater than or equal to $ MID $ direct total answer. then consider the internal matching, from small to large sweep, find another such that the two together is greater than the minimum MID $ $ equal value, and deleting nodes maybe cumulative answer to the last remaining parent node upload the longest chain inside the line.

 

$Code$

 

#include<iostream>
#include<cstdio>
#include<cstring>
#include<set>
#include<algorithm>
#define il inline
#define Rg register
#define go(i,a,b) for(Rg int i=a;i<=b;++i)
#define yes(i,a,b) for(Rg int i=a;i>=b;--i)
#define e(i,u) for(Rg int i=b[u];i;i=a[i].nt)
#define mem(a,b) memset(a,b,sizeof(a))
#define v(i) a[i].v
#define w(i) a[i].w
#define ll long long
#define db double
#define IT multiset<ll>::iterator
#define inf 2147483647
using namespace std;
il int read()
{
    Rg int x=0,y=1;char c=getchar();
    while(c<'0'||c>'9'){if(c=='-')y=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+c-'0';c=getchar();}
    return x*y;
}
const int N=50010;
int n,m,b[N],ct;
ll d1[N],d2[N],l=inf,r,mid,as;
struct node{int v,w,nt;}a[N*2];
il void add(int u,int v,int w){a[++ct]=(node){v,w,b[u]};b[u]=ct;}
il void dfs1(int u,int ft)
{
    e(i,u)
    {
        if(v(i)==ft)continue;
        dfs1(v(i),u);
        if(d1[v(i)]+w(i)>d1[u]){d2[u]=d1[u];d1[u]=d1[v(i)]+w(i);}
        else d2[u]=max(d2[u],d1[v(i)]+w(i));
    }
}
il ll dfs(int u,int fa)
{
    multiset<ll>q;q.clear();
    e(i,u)
    {
        if(v(i)==fa)continue;
        ll val=dfs(v(i),u)+w(i);
        if(val>=mid)ct++;
        else q.insert(val);
    }
    ll ret=0;
    while(q.size())
    {
        IT i=q.begin();
        IT j=q.lower_bound(mid-*i);
        if(((i==j)&&q.count(*i)==1))j++;
        if(j==q.end()){ret=max(ret,*i);q.erase(i);continue;}
        ct++;q.erase(q.find(*i));q.erase(q.find(*j));
    }
    return ret;
}
il bool ck()
{
    ct=0;dfs(1,0);
    if(ct>=m)return 1;return 0;
}
int main()
{
    n=read(),m=read();
    go(i,1,n-1){Rg int u=read(),v=read(),w=read();add(u,v,w);add(v,u,w);l=min(l,(ll)w);}
    dfs1(1,0);
    go(i,1,n)r=max(r,d1[i]+d2[i]);
    if(m==1){printf("%lld\n",r);return 0;}
    r+=1;
    while(l<=r)
    {
        mid=(l+r)>>1;
        if(ck())as=mid,l=mid+1;
        else r=mid-1;
    }
    printf("%lld\n",as);
    return 0;
}
View Code

 

 

 

Guess you like

Origin www.cnblogs.com/forward777/p/11403455.html