85分,求dalao查错
查看原帖
85分,求dalao查错
28702
a253774060楼主2017/10/25 19:53

用的是二分答案+树上差分。

求lca用的是tarjan。

求完lca后重新dfs了一遍,复用了一些数组。

验证答案的时候是按照dfs得到的后序遍历的顺序循环的,保证每个节点都在所有子节点访问到后才被访问。

'''cpp

#include<cstdio>
#include<cstring>
#include<algorithm>
int n,m,cnt,head[300001],qcnt,qhead[300001],d[300001],idx,fa[300001],f[300001],max,road[300001],vis[300001];
bool u[300001];
struct edge{
    int nxt,to,d;
}e[600001];
struct query{
    int nxt,to,idx;
}q[600001];
struct qinfo{
    int x,y,lca,d;
}info[300001];
int get(){
    int num=0;
    char c=getchar();
    while(c<'0' || c>'9') c=getchar();
    while(c>='0' && c<='9'){
        num=(num<<1)+(num<<3)+c-'0';
        c=getchar();
    }
    return num;
}
inline void add(int x,int y,int z){
    ++cnt;
    e[cnt].nxt=head[x];
    e[cnt].to=y;
    e[cnt].d=z;
    head[x]=cnt;
}
inline void qadd(int x,int y,int z){
    ++qcnt;
    q[qcnt].nxt=qhead[x];
    q[qcnt].to=y;
    q[qcnt].idx=z;
    qhead[x]=qcnt;
}
int find(int x){
    if(fa[x]==0) return x;
    else return fa[x]=find(fa[x]);
}
void lca(int x,int deep){
    int v;
    u[x]=true; d[x]=deep;
    for(int i=head[x];i;i=e[i].nxt){
        v=e[i].to;
        if(!u[v]){
            lca(v,deep+e[i].d);
            fa[v]=x;
        }
    }
    for(int i=qhead[x];i;i=q[i].nxt){
        v=q[i].to;
        if(u[v]){
            idx=q[i].idx;
            info[idx].x=x;
            info[idx].y=v;
            info[idx].lca=find(v);
            info[idx].d=deep+d[v]-(d[fa[v]]<<1);
        }
    }
}
void initdfs(int x){
    int v;
    for(int i=head[x];i;i=e[i].nxt){
        v=e[i].to;
        if(v!=fa[x]){
            fa[v]=x; d[v]=e[i].d;
            initdfs(v);
        }
    }
    vis[++vis[0]]=x;
}
bool comp(const qinfo &a,const qinfo &b){
    return a.d>b.d;
}
bool check(int ans){
    cnt=0;
    memset(road,0,sizeof(road));
    for(int i=1;i<=m;++i){
        if(info[i].d<=ans) break;
        ++road[info[i].x]; ++road[info[i].y]; road[info[i].lca]-=2;
        ++cnt;
    }
    int v;
    for(int i=1;i<n;++i){
        v=vis[i];
        if(road[v]==cnt && max-d[v]<=ans) return true;
        road[fa[v]]+=road[v];
    }
    return false;
}
int main(){                      
    n=get(); m=get();
    int a,b,t;
    for(int i=1;i<n;++i){
        a=get(); b=get(); t=get();
        add(a,b,t); add(b,a,t);
    }
    for(int i=1;i<=m;++i){
        a=get(); b=get();
        qadd(a,b,i); qadd(b,a,i);
    }
    lca(1,0);
    initdfs(1);
    std::sort(info+1,info+m+1,comp);
    int l=0,r=max=info[1].d,mid;
    while(l<r){
        mid=(l+r)>>1;
        if(check(mid)) r=mid;
        else l=mid+1;
    }
    printf("%d",l);
    return 0;
}
'''
2017/10/25 19:53
加载中...