# 13 WA 猛歆求助
查看原帖
# 13 WA 猛歆求助
106738
_Felix楼主2020/11/26 08:54

萌新求助

原来是TLE2个点,加了预处理lca 结果就wa on #13了 不知道哪里错了

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=3e5+10;
int n,m;
int e,to[N<<1],hd[N],nxt[N<<1],eval[N<<1];
int dep[N],sum[N],f[N][25],dist[N],pre[N];
struct node{
    int u,v;
}q[N];

void add(int x,int y,int z){ to[++e]=y; eval[e]=z; nxt[e]=hd[x]; hd[x]=e; }
int bmax(int x,int y){ return (x>y)?x:y; }
void dfs(int u,int fa){
    for(int i=1;i<=19;i++)
        f[u][i]=f[f[u][i-1]][i-1];
    for(int i=hd[u];i;i=nxt[i]){
        int v=to[i]; if(fa==v) continue;
        dep[v]=dep[u]+1; f[v][0]=u; dist[v]=dist[u]+eval[i];
        dfs(v,u);
    }
    return;
}//ok
void dfs2(int u,int fa){
    for(int i=hd[u];i;i=nxt[i]){
        int v=to[i]; if(fa==v) continue;
        dfs2(v,u); sum[u]+=sum[v];
    }
    return;
}//ok
inline int lca(int x,int y){
    if(dep[x]<dep[y]) swap(x,y);
    for(int i=19;i>=0;i--)
        if(dep[f[x][i]]>=dep[y]) x=f[x][i];
    if(x==y) return x;
    for(int i=19;i>=0;i--)
        if(f[x][i]!=f[y][i]) x=f[x][i],y=f[y][i];
    return x=y=f[x][0];
}//ok
inline void insert(int x,int y,int t){
    sum[x]+=1; sum[y]+=1; sum[t]-=2;
}//ok
inline int query(int cnt){
    int ret=0; dfs2(1,0);
    for(int i=1;i<=n;i++)
        if(sum[i]==cnt)
            ret=bmax(ret,dist[i]-dist[f[i][0]]);
    return ret;
}//ok
inline bool check(int val){
    for(int i=1;i<=n;i++) sum[i]=0;
    int mx=0; int cnt=0;
    for(int i=1;i<=m;i++) {
        int x=q[i].u,y=q[i].v;
        int t=pre[i],dis=dist[x]+dist[y]-2*dist[t];
        if(dis>val) insert(x,y,t),mx=bmax(mx,dis),++cnt;//覆盖路径?
    }
    return (mx-query(cnt)<=val);
}
int solve(){
    int l=0,r=1e8,ans=0;
    while(l<=r){
        int mid=(l+r)>>1;
        if(check(mid)) r=mid-1,ans=mid;
        else l=mid+1;
    }
    return ans;
}//ok
int main(){
 //   freopen("transport1.in","r",stdin);
  //  freopen("mine.out","w",stdout);
    scanf("%d%d",&n,&m);
    for(int i=1,u,v;i<n;i++){
        int w;
        scanf("%d%d%d",&u,&v,&w);
        add(u,v,w); add(v,u,w);
    }
    dfs(1,0);
    for(int i=1;i<=m;i++)
        scanf("%d%d",&q[i].u,&q[i].v),pre[i]=lca(q[i].u,q[i].v);
    printf("%d\n",solve());
    return 0;
}
/*
传输计划。
一棵树 有很多个运输计划,每个运输计划形如:有一艘船需要从 $u_i$ 号星球走最短路去 $v_i$ 号星球去。
显然,飞船驶过一条航道是需要时间的,对于航道 $j$,任意飞船驶过它所花费的时间为 $t_j$,并且任意两艘飞船之间不会产生任何干扰。
允许小 P 把某条航道改造成虫洞,飞船驶过虫洞不消耗时间。
如果小 P 可以自由选择将哪一条航道改造成虫洞, 试求完成 $m$ 个运输任务所需要的最短时间是多少?
n m 3e5 应该要log。。 

二分最长路径 然后check 树上差分维护都被访问的一条路径 复杂度是$O(n \log^2 n)$

为什么答案那么大 是不是query求错了。。。
*/
2020/11/26 08:54
加载中...