BZOJ 2599 Race

Posted on 2017-03-10 11:57  ziliuziliu  阅读(101)  评论(0编辑  收藏  举报

点分写挂调一上午。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<set>
#define maxv 200050
#define maxe 400050
#define maxk 1000050
#define inf 1000000007
using namespace std;
int n,k,x,y,w,g[maxv],nume=1,ans=inf,lab[maxk],root,sum;
int dis[maxv],size[maxv],dep[maxv],mx[maxv],s1[maxv],s2[maxv],top=0;
bool vis[maxv];
struct edge
{
    int v,w,nxt;
}e[maxe];
int read()
{
    char ch;int data=0;
    while (ch<'0' || ch>'9') ch=getchar();
    while (ch>='0' && ch<='9')
    {
        data=data*10+ch-'0';
        ch=getchar();
    }
    return data;
}
void addedge(int u,int v,int w)
{
    e[++nume].v=v;e[nume].w=w;
    e[nume].nxt=g[u];
    g[u]=nume;
}
void get_root(int x,int fath)
{
    size[x]=1;mx[x]=0;
    for (int i=g[x];i;i=e[i].nxt)
    {
        int v=e[i].v;
        if (!vis[v] && v!=fath)
        {
            get_root(v,x);
            size[x]+=size[v];mx[x]=max(mx[x],size[v]);
        }
    }
    mx[x]=max(mx[x],sum-size[x]);
    if (mx[x]<mx[root]) root=x;
}
void dfs1(int x,int fath)
{
    if (dis[x]<=k) {s1[++top]=dis[x];s2[top]=dep[x];}
    for (int i=g[x];i;i=e[i].nxt)
    {
        int v=e[i].v;
        if (vis[v] || v==fath) continue;
        dis[v]=dis[x]+e[i].w;dep[v]=dep[x]+1;
        dfs1(v,x);
    }
}
void dfs2(int x,int fath)
{
    if (dis[x]<=k) lab[dis[x]]=inf;
    for (int i=g[x];i;i=e[i].nxt)
    {
        int v=e[i].v;
        if (vis[v] || v==fath) continue;
        dis[v]=dis[x]+e[i].w;dep[v]=dep[x]+1;
        dfs2(v,x);
    }
}
void solve(int x)
{
    vis[x]=true;
    for (int i=g[x];i;i=e[i].nxt)
    {
        int v=e[i].v;
        if (vis[v]) continue;
        dis[v]=e[i].w;dep[v]=1;
        top=0;dfs1(v,0);
        for (int j=1;j<=top;j++) ans=min(ans,s2[j]+lab[k-s1[j]]);
        for (int j=0;j<=top;j++) lab[s1[j]]=min(lab[s1[j]],s2[j]);
    }
    for (int i=g[x];i;i=e[i].nxt)
    {
        int v=e[i].v;
        if (vis[v]) continue;
        dis[v]=e[i].w;dep[v]=1;
        dfs2(v,0);
    }
    for (int i=g[x];i;i=e[i].nxt)
    {
        int v=e[i].v;if (vis[v]) continue;
        sum=size[v];root=0;get_root(v,0);
        solve(root);
    }
}
int main()
{
    n=read();k=read();
    for (int i=1;i<=k;i++) lab[i]=inf;mx[0]=inf;
    for (int i=1;i<=n-1;i++)
    {
        x=read();y=read();w=read();x++;y++;
        addedge(x,y,w);addedge(y,x,w);
    }
    sum=n;root=0;get_root(1,0);
    solve(root);
    if (ans==inf) printf("-1\n");
    else printf("%d\n",ans); 
    return 0;
}