zoukankan      html  css  js  c++  java
  • luogu P2680 运输计划 65分做法

    临近(noip,AK)不太现实,暴力才是王道,大佬无视

    这里只介绍(65)分做法


    (m==1) 的情况
    很明显 就一条路径,当然要贪心选着一条路径路上的最大的边喽
    傻逼分(get 20)

    (n,m<=100)
    想怎么暴力怎么暴力,反正不会TLE
    **枚举割哪一条边 **
    枚举每条路径dfs()一边 寻找最大值
    最后取min 就好了
    复杂度(O(n^3))
    又get 10分

    很明显的二分,我就是不会(⊙o⊙)


    一条链子的时候并且n<=3000
    求路径的和的时候可以用前缀和维护一下
    达到O(1)的查询
    使得②的复杂度降低了一个(O(n))
    最终复杂的(O(n^2))
    get 15分 啦

    一条链子的时候并且n>=3000
    二分他的最大长度
    当然得利用③的O(1)查询啦
    考虑check函数
    如果第i次运货路线大于x(也就是二分的mid)
    那么要割掉的点一定在(l_{i})(r_{i})之间
    维护一下左边界和右边界就好了(如果不成立的话直接return 0)
    最后在左边界和右边界查询最大就好啦
    最终复杂度O((nlogn)
    get 20分

    最终得分 (65)

    打死我也不会lca

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    using namespace std;
    const int maxn=100007;
    int n,m;
    int S[maxn],T[maxn],num[maxn];
    int noip[maxn],cz[maxn];
    struct edge{
        int v,nxt,q;
    }e[maxn<<1];
    int head[maxn<<1],tot;
    int a[maxn],sum[maxn];
    int tot_30,max_30,flag_30;
    void add_edge(int u,int v,int q)
    {
        e[++tot].v=v;
        e[tot].q=q;
        e[tot].nxt=head[u];
        head[u]=tot;
    }
    inline int read()
    {
        int x=0,f=1;char s=getchar();
        while(s<'0'||s>'9') {if(s=='-')f=-1;s=getchar();}
        while(s>='0'&&s<='9') {x=x*10+s-'0',s=getchar();}
        return x*f;
    }
    void dfs_30(int u,int f,int end)
    {
        if(u==end) {
            flag_30=1;
            return;
        }
        for(int i=head[u];i;i=e[i].nxt)
        {   
            int v=e[i].v;
            if(v==f) continue;      
    
            int tmp=max_30;
            tot_30+=e[i].q;
            max_30=max(max_30,e[i].q);
            
            dfs_30(v,u,end);
            if(flag_30) return;
    
            tot_30-=e[i].q;
            max_30=tmp;
        }
    }
    int check(int x)
    {
        int l=1,r=n;
        int zz=0;
        for(int i=1;i<=m;++i)
        {
            if(num[i] > x)
            {
                zz=max(zz,num[i]);
                if(l >= T[i]) return 0;
                if(r <= S[i]) return 0;
                l=max(l,S[i]);
                r=min(r,T[i]);
            }
        }
        int tmp=0;
        for(int i=l+1;i<=r;++i)
            tmp=max(tmp,a[i]);
        zz-=tmp;
        return zz > x ? 0 : 1;
    }
    int main()
    {
        n=read(),m=read();
        int flag_lz=0;
        for(int i=1;i<n;++i)
        {
            int a=read(),b=read(),c=read();
            if(a==b+1||b==a+1) flag_lz++;
            add_edge(a,b,c);
            add_edge(b,a,c);
        }
        for(int i=1;i<=m;++i)
            S[i]=read(),T[i]=read();
        if(m==1)
        {
            dfs_30(S[1],0,T[1]);
            printf("%d
    ",tot_30-max_30);
            return 0;
        }
        if(n<=1000)
        {
            int ans=0x3f3f3f3f;
            for(int i=1;i<=2*n-2;i+=2) // 枚举航道
            {
                int tmp=e[i].q;
                e[i].q=e[i+1].q=0;
                int dsr=0;
                for(int j=1;j<=m;++j) //遍历客户
                {
                    flag_30=tot_30=0;
                    dfs_30(S[j],0,T[j]);
                    dsr=max(dsr,tot_30);
                }
                ans=min(ans,dsr);
                e[i].q=e[i+1].q=tmp;        
            }
            printf("%d
    ",ans);
            return 0;
        }
        if(flag_lz==n-1)
        {
            for(int i=1,j=2;i<=2*(n-1);i+=2,j++)
                a[j]=e[i].q;
            for(int i=2;i<=n;++i)
                sum[i]=sum[i-1]+a[i];
            for(int i=1;i<=m;++i)
            {
                if(S[i]>T[i]) swap(S[i],T[i]);
                num[i]=sum[T[i]]-sum[S[i]];
            }
            int l=1,r=3e8;
            int ans;
            while(l<=r)
            {
                int mid=(l+r)>>1;
                if(check(mid)) ans=mid,r=mid-1;
                else l=mid+1;
            }
            printf("%d
    ",ans);
            return 0;
        }
        return 0;
    }
    
  • 相关阅读:
    HDU-统计难题
    POJ-A Simple Problem with Integers
    HDU-I Hate It
    个人站立会议06
    个人站立会议05
    个人站立会议04
    易校小程序典型用户需求分析
    个人站立会议03
    个人第二次晚间站立总结会议
    个人站立会议02
  • 原文地址:https://www.cnblogs.com/dsrdsr/p/9722188.html
Copyright © 2011-2022 走看看