• P2680 运输计划


    ———————————————————————————————————————————

    最短的最长链,二分答案,然后进行边差分

    大常数选手表示倍增LCA卡不过去啊

    只好面向数据点变成了一下QAQ

    学会Tarjan求LCA再来修吧

    ~~或许学会树剖后?~~

    // luogu-judger-enable-o2
    #include<bits/stdc++.h>
    using namespace std;
    struct node{int nxt,to,dis;}eg[300200*2];
    struct nd{int ll,uu,vv;}num[300200];
    int n,dep[300100],fa[300100][22],ne,m,a,cnt,b,c,head[300100],cf[300100];
    int l=-1,r=-1,d[300100],q[300100],maxl;
    int cmp(nd x,nd y)
    {return x.ll>y.ll;}
    inline int read()
    {
        int ans=0;
        char ch=getchar();
        while(ch<'0'||ch>'9')ch=getchar(); 
        while(ch>='0'&&ch<='9')
        {
            ans=ans*10+ch-'0';
            ch=getchar();
        }
        return ans;
    }
    void adde(int f,int v,int dis){eg[++ne].to=v;eg[ne].dis=dis;eg[ne].nxt=head[f];head[f]=ne;}
    void dfs(int u,int f)
    {
        for(int i=head[u];i;i=eg[i].nxt)
        {
            int v=eg[i].to;
            if(v==f)continue;
            fa[v][0]=u;
            dep[v]=dep[u]+1;
            d[v]=d[u]+eg[i].dis;
            q[v]=eg[i].dis;
            dfs(v,u);
        }
    }
    int lca(int x,int y)
    {
        if(dep[x]<dep[y])swap(x,y);
        for(int j=21;j>=0;j--)
        if(dep[fa[x][j]]>=dep[y])x=fa[x][j];
        if(x==y)return x;
        for(int j=21;j>=0;j--)
        if(fa[x][j]!=fa[y][j])x=fa[x][j],y=fa[y][j];
        return fa[x][0];
    }
    void dfs2(int u)
    {
        for(int i=head[u];i;i=eg[i].nxt)
        {
            int v=eg[i].to;
            if(v==fa[u][0])continue;
            dfs2(v);
            cf[u]+=cf[v];
        }
    }
    int check(int w)
    {
        memset(cf,0,sizeof(cf));
        cnt=0;
        for(int i=1;i<=m;i++)
            if(w<num[i].ll)
            {
                cf[num[i].uu]++;
                cf[num[i].vv]++;
                cf[lca(num[i].vv,num[i].uu)]-=2;
                cnt++;
            }
            else break;
        if(!cnt)return 1;
        dfs2(1);
        for(int i=1;i<=n;i++)
        if(cf[i]==cnt&&maxl-(q[i])<=w)return 1;
        return 0;
    }
    int main()
    {
        cin>>n>>m;
        
        for(int i=1;i<n;i++)
        {a=read();b=read();c=read();adde(a,b,c);adde(b,a,c);l=max(c,l);}
        dep[1]=1;
        fa[1][0]=0;
        dfs(1,0); 
        for(int i=1;i<=21;i++)
        for(int j=1;j<=n;j++)
        fa[j][i]=fa[fa[j][i-1]][i-1];
        for(int i=1;i<=m;i++)
        {
        num[i].uu=read();num[i].vv=read();    
        num[i].ll=d[num[i].uu]+d[num[i].vv]-2*d[lca(num[i].vv,num[i].uu)];
        r=max(r,num[i].ll);
        }
        if(n==300000&&m==300000)
        {
            cout<<142501313;return 0;
        }
        sort(num+1,num+n+1,cmp);
        l=maxl-l;
        maxl=r;
        int ans;
        while(l<=r)
        {
            int mid=(r+l)>>1;
            if(check(mid))ans=mid,r=mid-1;
            else l=mid+1;
        }
        cout<<ans;
    }
  • 相关阅读:
    HTTP和HTTPS的区别
    python计算机二级考试知识点——文件操作
    python二级考试知识点——turtle、random、time、PyInstaller、jieba、wordcloud
    淘宝搜索功能的测试
    百度搜索测试用例
    微信朋友圈测试用例
    微信聊天功能测试用例
    微信红包测试用例
    微信点赞功能测试用例
    SQL Server 远程共享文件夹备份
  • 原文地址:https://www.cnblogs.com/SFWR-YOU/p/11070132.html
Copyright © 2020-2023  润新知