【2015】

D2T3 运输计划

*认真读题,不是问完成每一个任务的总用时而是找最长用时

#include<bits/stdc++.h>
#define ri register int
#define ll long long
#define logM 24
#define For(i,l,r) for(ri i=l;i<=r;i++)
#define Dfor(i,r,l) for(ri i=r;i>=l;i--)
using namespace std;
const int M=3e5+5; 
int n,m,head[M],cnt,maxa;
struct node{
    int to,nxt,w;
}e[M<<1];
inline ll read(){
    ll f=1,sum=0;
    char ch=getchar();
    while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
    while(isdigit(ch)){sum=(sum<<1)+(sum<<3)+(ch^48);ch=getchar();}
    return f*sum;
}
inline void add(int u,int v,int w){
    e[cnt].w=w;
    e[cnt].nxt=head[u];
    head[u]=cnt;
    e[cnt].to=v;
    cnt++;
}
int p[M],dis[M],dep[M],gra[M][logM],topre[M];
inline void dfs(int u,int fa){
    p[++cnt]=u;
    for(ri i=1;i<logM;i++){
        gra[u][i]=gra[gra[u][i-1]][i-1];
        if(!gra[u][i])break;
    }
    for(ri i=head[u];~i;i=e[i].nxt){
        int v=e[i].to;
        if(v==fa) continue;
        dis[v]=dis[u]+e[i].w;
        dep[v]=dep[u]+1;
        gra[v][0]=u;
        topre[v]=e[i].w;
        dfs(v,u);
    }
}
inline int lca(int x,int y){
    if(dep[x]>dep[y]) swap(x,y);
    for(int i=logM-1;i>=0;i--){
        if(dep[gra[y][i]]>=dep[x]) y=gra[y][i];
    }
    for(int i=logM-1;i>=0;i--){
        if(gra[y][i]!=gra[x][i]) x=gra[x][i],y=gra[y][i];
    }
    if(x!=y) x=gra[x][0];
    return x;
}
int f[M],d[M];
int a[M],b[M],l[M],maxx,minn;
inline bool check(int k){
    memset(f,0,sizeof(f)),cnt=0;
    For(i,1,m){
        if(d[i]>k) f[a[i]]++,f[b[i]]++,f[l[i]]-=2,cnt++;
    }
    Dfor(i,n,1){
        f[gra[p[i]][0]]+=f[p[i]];
        if(topre[p[i]]>=maxx-k&&f[p[i]]==cnt) return 1;
    }
    return 0;
}
inline int ef(int l,int r){
    while(l<r){
        int mid=(l+r)>>1;
        if(check(mid)) r=mid;
        else l=mid+1;
    }
    return l;
}
int main(){
    n=read(),m=read();
    memset(head,-1,sizeof(head));
    For(i,1,n-1){
        int u=read(),v=read(),w=read();
        add(u,v,w),add(v,u,w);
        maxa=max(maxa,w);
    }
    cnt=0,dep[0]=-1,dep[1]=1;
    dfs(1,0);
    For(i,1,m){
        a[i]=read(),b[i]=read();
        l[i]=lca(a[i],b[i]);
        d[i]=dis[a[i]]+dis[b[i]]-(dis[l[i]]<<1);
        maxx=max(maxx,d[i]);
    }
    printf("%d
",ef(maxx-maxa,maxx+1));
    return 0;
}
View Code

 

原文地址:https://www.cnblogs.com/jian-song/p/11867032.html