记录编号 539512 评测结果 AAAAAAAAAAAAAAAAAAAA
题目名称 [NOIP 2015]运输计划 最终得分 100
用户昵称 GravatarWxjianF019 是否通过 通过
代码语言 C++ 运行时间 2.986 s
提交时间 2019-08-07 23:42:49 内存使用 41.12 MiB
显示代码纯文本
#include<stdio.h>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
const int maxn=3e5+5;
int n,m,q[maxn][3],max_dis=0;
vector<int>v[maxn],w[maxn];
int a[maxn],dis[maxn],mark[maxn],fa[maxn],size[maxn],dep[maxn],top[maxn],son[maxn],pos[maxn],cnt;
void Dfs(int rt){
    size[rt]=1;
    for(int i=0;i<v[rt].size();i++){
        int to=v[rt][i];
        if(!size[to]){
            fa[to]=rt;
            dis[to]=dis[rt]+w[rt][i];
            dep[to]=dep[rt]+1;a[to]=w[rt][i];
            Dfs(to);size[rt]+=size[to];
            if(size[to]>size[son[rt]])son[rt]=to;
        }
    }
}
void Dfs(int rt,int tp){
    top[rt]=tp,pos[rt]=++cnt;
    if(son[rt])Dfs(son[rt],tp);
    for(int i=0;i<v[rt].size();i++)
        if(!pos[v[rt][i]])Dfs(v[rt][i],v[rt][i]);
}
int LCA(int x,int y){
    while(top[x]^top[y]){
        if(dep[top[x]]<dep[top[y]])swap(x,y);
        x=fa[top[x]];
    }
    if(dep[x]>dep[y])swap(x,y);
    return x;
}
void MArk(int x,int y){
    if(pos[x]<=pos[y])
    mark[pos[x]]++,mark[pos[y]+1]--;
}
void Mark(int x,int y){
    while(top[x]^top[y]){
        if(dep[top[x]]<dep[top[y]])swap(x,y);
        MArk(top[x],x);
        x=fa[top[x]];
    }
    if(dep[x]>dep[y])swap(x,y);
    if(x!=y)MArk(son[x],y);
}
bool Judge(int mid){
    int tot=0;memset(mark,0,sizeof mark);
    for(int i=0;i<m;i++)if(q[i][2]>mid)tot++,Mark(q[i][0],q[i][1]);
    if(!tot)return true;
    for(int i=2;i<=n;i++)mark[i]+=mark[i-1];
    for(int i=2;i<=n;i++)
        if(mark[pos[i]]==tot&&max_dis-a[i]<=mid)return true;
    return false;
}
int main(){
    freopen("transport.in","r",stdin);freopen("transport.out","w",stdout);
    scanf("%d%d",&n,&m);
    for(int x,y,z,i=1;i<n;i++){
        scanf("%d%d%d",&x,&y,&z);
        v[x].push_back(y),w[x].push_back(z);
        v[y].push_back(x),w[y].push_back(z);
    }
    Dfs(1),Dfs(1,1);
    for(int x,y,i=0;i<m;i++){
        scanf("%d%d",&x,&y);
        q[i][0]=x;q[i][1]=y;q[i][2]=dis[x]+dis[y]-2*dis[LCA(x,y)];
        max_dis=max(max_dis,q[i][2]);
    }
    int l=0,r=max_dis;
    while(l<r){
        int mid=l+r>>1;
        if(Judge(mid))r=mid;
        else l=mid+1;
    }
    printf("%d\n",l);
    return 0;
}