• 2016 Benelux Algorithm Programming Contest (BAPC 16)


    Time:2018.4.27  17:00-22:00

    Link


    A

    题意

    分析

    几何最短路,留坑


    B    solved by ym

    题意

    ym:按题意模拟即可 


    C    solved by ym

    题意

    ym:赛时czh的代码FST了,按题意模拟不断删点,实际上和拓扑排序删点相似

    #include<bits/stdc++.h>
    using namespace std;
    
    int head[300003*2],nxt[300003*2],to[300003*2],tot;
    int C,P,X,L;
    int d[200005],del[200005];
    bool vis[200005];
    
    
    void add(int u,int v)
    {
        ++tot;
        to[tot]=v;
        nxt[tot]=head[u];
        head[u]=tot;
    }
    
    void topsort()
    {
        queue<int>q;
        q.push(L);
        vis[L]=1;
        while(!q.empty())
        {
            int u=q.front();
            q.pop();
            for(int i=head[u];i;i=nxt[i])
            {
                int v=to[i];
                del[v]++;
                if(!vis[v]&&del[v]>=((d[v]+1)/2))
                {
                    vis[v]=1;
                    q.push(v);
                }
            }
        }
    }
    
    int main()
    {
        scanf("%d%d%d%d",&C,&P,&X,&L);
        int u,v;
        for(int i=1;i<=P;i++)
        {
            scanf("%d%d",&u,&v);
            d[u]++;
            d[v]++;
            add(u,v);
            add(v,u);
        }
        topsort();
        if(vis[X])
        {
            cout<<"leave"<<endl;
        }
        else
            cout<<"stay"<<endl;
        return 0;
    }

    D

    题意

    现有n艘船需要通过桥,但桥很累不想一直连通,所以在“闲”的时候可以不连通,但每艘船不可以等待超过30min,升/降桥会花费60s,每艘船通过花费20s,船一艘一艘的通过,给出每艘船到达桥的时间T_i,问船工作的最小时间(升降+连通) ( n<=4000,T_i<=1e5,i<j && T_i+20<=T_j )

    分析

    ym:令f_i为前艘船通过的最小时间,枚举和i一起通过的船j(j<=i),转移即可

    时间复杂度O(n^2)

    #include<bits/stdc++.h>
    using namespace std;
    
    int dp[4005],n,a[4005];
    
    int main()
    {
    
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
            dp[i]=1000000+7;
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
        }
        dp[1]=140;
        for(int i=2;i<=n;i++)
        {
            for(int j=1;j<=i;j++)
            {
                dp[i]=min(dp[i], dp[j-1]+120+20+a[i]-min(a[j]+1800,a[i]-(i-j)*20));
            }
        }
        printf("%d
    ",dp[n]);
        return 0;
    }

    E

    题意

    给一个n个点m条边的无向图,给出起点到终点的路径最大值,问满足路径和小于max的所有路径中每条路径的最大值最小(n<=1e4,m<=1e5,w<=1e9)

    分析

    ym:比赛时候天马行空的考虑完全图路径很多的情况==,实际上至于只需要关注每一个点和边的访问次数,便能正确得出时间复杂度,例如在有权的无向图中的单源最短路,由于每个点只会被取出一次所以时间复杂度为(VlogV),回到此题,二分答案(最短路具有单调性)最短路检查即可(边权w如果大于mid,相当于看做不选择这条边即可,在剩下的点中求最短路径)

    时间复杂度O(nlog2n)

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    const int maxn=210000;
    priority_queue<pair<LL,int>,vector<pair<LL,int> >,greater<pair<LL,int> > > q;
    const LL INF=1e18;
    LL dis[110000];
    int vis[110000];
    int n,m,x;
    
    int head[maxn],nxt[maxn],to[maxn],tot;
    LL w[210000];
    
    void add(int u,int v,int c)
    {
        ++tot;
        to[tot]=v;
        w[tot]=c;
        nxt[tot]=head[u];
        head[u]=tot;
    }
    
    LL dij(int limt)
    {
        for(int i=1;i<=n;i++)
            dis[i]=INF,vis[i]=0;
        dis[1]=0;
        q.push(make_pair(0,1));
        while(!q.empty())
        {
            int now=q.top().second;
            q.pop();
            if(vis[now])
                continue;
            vis[now]=1;
            for(int i=head[now];i!=0;i=nxt[i])
            {
                if (w[i]<=limt&&dis[to[i]]>dis[now]+w[i])
                {    dis[to[i]]=dis[now]+w[i];
                    q.push(make_pair(dis[to[i]],to[i]));
                }
            }
        }
        return dis[n];
    
    }
    LL dist;
    int ans;
    int check(int x)
    {
        return dij(x)<=dist;
    }
    
    int main()
    {
        scanf("%d%d%d", &n, &m,&x);
        int u,v;
        int c;
        for(int i=1;i<=m;i++)
        {
            scanf("%d%d%d",&u,&v,&c);
            add(u,v,c);
            add(v,u,c);
        }
        dist=dij(1000000000);
        dist=dist*(100LL+x)/100;
        int l=1,r=1000000000;
        while (l<=r)
        {
              int mid=(l+r)/2;
              if (check(mid)) ans=mid,r=mid-1;
              else l=mid+1;
        }
        printf("%d
    ",ans);
        return 0;
    }

    F

    题意

    分析

    几何模拟,留坑


    G

    题意

     

    分析

     ym:可做几何,待补


    H

    题意

     

    分析

    ym:爆搜剪纸,待补


    I      solved by czh&ym

    题意

    ym:按题意模拟即可


    J    solved by ym&czh

    题意

    分别给出n个学生和n个导师的二维坐标,定义两点的dis:|x1-x2|+|y1-y2|,现要一 一配对,要使最大的dis最小,问每个最大所有情况最小的dis

    分析

    ym:算法理解不深刻,只会套板子

             二分图是根据边集,不断找增广路,故可以二分答案,二分图check,即在找增广路的时候加上约束条件

    #include<bits/stdc++.h>
    #define ll long long
    using namespace std;
    const int maxn = 100+7;
    
    int n,f[maxn],v[maxn];
    ll sx[maxn],sy[maxn],tx[maxn],ty[maxn];
    
    ll _abs(ll x){
        if(x>0) return x;
        else return -x;
    }
    
    ll dis(int i,int j){
        return _abs(sx[i]-tx[j])+_abs(sy[i]-ty[j]);
    }
    
    bool found(int x,ll mid)
    {
        for(int i=1;i<=n;i++)
        {
            if(dis(x,i)<=mid&&!v[i])
            {
                v[i]=1;
                if(f[i]==0||found(f[i],mid))
                {
                    f[i]=x;
                    return true;
                }
            }
        }
        return false;
    }
    
    bool check(ll mid)
    {
        for(int i=1;i<=n;i++)
            f[i]=0;
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=n;j++) v[j]=0;
            if(!found(i,mid))
                return false;
        }
        return true;
    }
    
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
            scanf("%lld%lld",&sx[i],&sy[i]);
        for(int i=1;i<=n;i++)
            scanf("%lld%lld",&tx[i],&ty[i]);
        bool flag=true;
        ll l=0,r=1000000000;
        while(l<r)
        {
            ll mid=(l+r)/2;
            if(check(mid))
            {
                r=mid;
            }
            else
                l=mid+1;
        }
        printf("%lld
    ",l);
        return 0;
    }

    K

    题意

    给出长度为L的圆形跑道,每S米至少放一个人,问方案数 

    分析

    ym:dp待补 


    L   solved by czh&ym

    题意

    ym:排序后检查相邻3项能否形成三角形即可


    Summary

    Ym这次表现看上去不错,,其实很惨,数据有锅,Link以Update,kattis数据正确(甚至很强,E卡我两个小时),以后比赛多读几道题,利于补题呀!!!

    Czh:

  • 相关阅读:
    第四次作业
    第三次作业
    java第三次作业
    java第二次作业
    java作业
    第一次作业
    第十一次作业
    第十次作业
    第九次作业
    第八次作业
  • 原文地址:https://www.cnblogs.com/Deadline/p/8965852.html
Copyright © 2020-2023  润新知