• Luogu P2680 运输计划


    题目链接:Click here

    Solution:

    我们要使最大值最小,显然二分

    二分一个最大值,小于等于最大值的路径就不用管了,看大于最大值的路径

    记录要使剩下的路径的最大值小于等于当前二分的值,要减去的最小边长maxd

    然后我们就是要查找是否有一条被剩下的所有路径都经过的,长度大于等于maxd边

    我们可以用树上差分来记录一条边被多少条路径经过

    对于一条路径,我们使(d[u]++)(d[v]++)(d[lca(u,v)]-2)(f[x])代表以(x)为根的子树(d)值之和

    对于任意(f[x]=tot),则说明(x)连向(fa[x])的这条边被所有路径都经过了

    用倍增求lca会T,所以我们用树剖来求lca(关于倍增,它死了>)

    Code:

    #include<bits/stdc++.h>
    using namespace std;
    const int N=3e5+1;
    int n,m,cnt,head[N],dis[N],fdis[N];
    int maxn,f[N][32],dif[N],dep[N];
    int son[N],sz[N],fa[N],top[N];
    struct Edge{int nxt,to,val;}edge[N<<1];
    struct Road{int ds,u,v,lca;}p[N];
    void ins(int x,int y,int z){
        edge[++cnt].nxt=head[x];
        edge[cnt].to=y;head[x]=cnt;
        edge[cnt].val=z;
    }
    void dfs1(int x,int fat){
        for(int i=head[x];i;i=edge[i].nxt){
            int y=edge[i].to;
            if(y==fat) continue;
            fa[y]=x;dep[y]=dep[x]+1;
            dis[y]=dis[x]+edge[i].val;
            fdis[y]=edge[i].val;
            dfs1(y,x);sz[x]+=sz[y];
            if(sz[y]>sz[son[x]]) son[x]=y;
        }sz[x]++;
    }
    void dfs2(int x,int topx){
        top[x]=topx;
        if(!son[x]) return ;
        dfs2(son[x],topx);
        for(int i=head[x];i;i=edge[i].nxt){
            int y=edge[i].to;
            if(y==fa[x]||y==son[x]) continue;
            dfs2(y,y);
        }
    }
    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;
    }
    int dist(int x,int y){
        return dis[x]+dis[y]-(dis[Lca(x,y)]<<1);
    }
    void getdif(int x){
        for(int i=head[x];i;i=edge[i].nxt){
            int y=edge[i].to;
            if(y==fa[x]) continue;
            getdif(y);dif[x]+=dif[y];
        }    
    }
    int check(int mid){
        int tot=0,maxd=0;
        memset(dif,0,sizeof(dif));
        for(int i=1;i<=m;i++){
            if(p[i].ds<=mid) continue;
            dif[p[i].u]++,dif[p[i].v]++;
            dif[p[i].lca]-=2;++tot;
            maxd=max(maxd,p[i].ds-mid);
        }getdif(1);
        for(int i=2;i<=n;i++)
            if(maxd<=fdis[i]&&dif[i]>=tot) return 1;
        return 0;
    }
    int read(){
        int x=0,f=1;char ch=getchar();
        while(!isdigit(ch)){if(ch=='-')f=-f;ch=getchar();}
        while(isdigit(ch)){x=x*10+ch-48;ch=getchar();}
        return x*f;
    }
    signed main(){
        n=read(),m=read();
        for(int i=1;i<n;i++){
            int x=read(),y=read(),z=read();
            ins(x,y,z),ins(y,x,z);
        }dfs1(1,0);dfs2(1,1);
        for(int i=1;i<=m;i++){
            int x=read(),y=read();
            p[i].u=x,p[i].v=y;
            p[i].lca=Lca(x,y);
            p[i].ds=dist(x,y);
            maxn=max(maxn,p[i].ds);
        }
        int l=0,r=maxn,re=-1;
        while(l<=r){
            int mid=l+r>>1;
            if(check(mid)) re=mid,r=mid-1;
            else l=mid+1;
        }printf("%d
    ",re);
        return 0;
    }
    
  • 相关阅读:
    使用koa+mongodb构建的仿知乎接口(二)
    使用koa+mongodb构建的仿知乎接口(一)
    flask学习笔记
    后端遇到一些问题
    前端项目一些细节总结
    python基础学习
    vue本地运行项目使用iframe的跨域问题
    hover状态下改变图片颜色的方式 悬停图片切换;css变量;悬停svg图片改变颜色;VUE
    深拷贝
    git初使用
  • 原文地址:https://www.cnblogs.com/NLDQY/p/11518644.html
Copyright © 2020-2023  润新知