zoukankan      html  css  js  c++  java
  • 洛谷 P2887 [USACO07NOV]防晒霜Sunscreen 解题报告

    P2887 [USACO07NOV]防晒霜Sunscreen

    题目描述

    To avoid unsightly burns while tanning, each of the C (1 ≤ C ≤ 2500) cows must cover her hide with sunscreen when they're at the beach. Cow i has a minimum and maximum SPF rating (1 ≤ minSPFi ≤ 1,000; minSPFi ≤ maxSPFi ≤ 1,000) that will work. If the SPF rating is too low, the cow suffers sunburn; if the SPF rating is too high, the cow doesn't tan at all........

    The cows have a picnic basket with L (1 ≤ L ≤ 2500) bottles of sunscreen lotion, each bottle i with an SPF rating SPFi (1 ≤ SPFi ≤ 1,000). Lotion bottle i can cover coveri cows with lotion. A cow may lotion from only one bottle.

    What is the maximum number of cows that can protect themselves while tanning given the available lotions?

    (C)个奶牛去晒太阳 (1 <=(C) <= 2500),每个奶牛各自能够忍受的阳光强度有一个最小值和一个最大值,太大就晒伤了,太小奶牛没感觉。

    而刚开始的阳光的强度非常大,奶牛都承受不住,然后奶牛就得涂抹防晒霜,防晒霜的作用是让阳光照在身上的阳光强度固定为某个值。

    那么为了不让奶牛烫伤,又不会没有效果。

    给出了(L)种防晒霜。每种的数量和固定的阳光强度也给出来了

    每个奶牛只能抹一瓶防晒霜,最后问能够享受晒太阳的奶牛有几个。

    输入输出格式

    输入格式:

    • Line 1: Two space-separated integers: (C) and (L)

    • Lines 2..(C+1): Line i describes cow i's lotion requires with two integers: (minSPFi) and (maxSPFi)

    • Lines (C+2)..(C+L+1): Line (i+C+1) describes a sunscreen lotion bottle (i) with space-separated integers: (SPFi) and (coveri)

    输出格式:

    A single line with an integer that is the maximum number of cows that can be protected while tanning


    (DINIC)周常写爆:(1/1)

    思路:s连每头牛边1,每头牛连合法的防晒霜边1,防晒霜连t使用次数,跑最大流即可。(此题也有别的解法)

    前后代码对比:
    54分:

    #include <cstdio>
    #include <cstring>
    #include <queue>
    using namespace std;
    int min(int x,int y){return x<y?x:y;}
    const int N=2508;
    const int inf=0x3f3f3f3f;
    int C,L,l[N],r[N],T;
    struct Edge
    {
        int next,to,w;
    }edge[N*N];
    int head[N<<2],cnt=-1;
    void add(int u,int v,int w)
    {
        edge[++cnt].next=head[u];edge[cnt].to=v;edge[cnt].w=w;head[u]=cnt;
    }
    int dep[N<<2],s[N<<2],pre[N<<2],used[N<<2],tot=0,ans=0;
    queue <int > q;
    void push(int x){s[++tot]=x;}
    void pop(){tot--;}
    bool bfs()
    {
        memset(dep,0,sizeof(dep));
        while(!q.empty()) q.pop();
        q.push(0);
        dep[0]=1;
        while(!q.empty()&&q.front()!=T)
        {
            int u=q.front();
            q.pop();
            for(int i=head[u];i!=-1;i=edge[i].next)
            {
                int v=edge[i].to,w=edge[i].w;
                if(!dep[v]&&w)
                {
                    dep[v]=dep[u]+1;
                    q.push(v);
                }
            }
        }
        return !q.empty();
    }
    int main()
    {
        scanf("%d%d",&C,&L);
        memset(head,-1,sizeof(head));
        T=C+L+1;
        for(int i=1;i<=C;i++)
        {
            scanf("%d%d",l+i,r+i);
            add(0,i,1),add(i,0,0);
        }
        int num,d;
        for(int i=1;i<=L;i++)
        {
            scanf("%d%d",&d,&num);
            for(int j=1;j<=C;j++)
                if(l[j]<=d&&d<=r[j])
                    add(j,i+C,1),add(i+C,j,0);
            add(i+C,T,num),add(T,i+C,0);
        }
        while(bfs())
        {
            push(0);
            memset(used,0,sizeof(used));
            memset(pre,0,sizeof(pre));
            while(tot)
            {
                if(s[tot]==T)
                {
                    int now=tot,id,m_min=inf;
                    while(pre[s[now]])
                    {
                        if(m_min>=edge[pre[s[now]]].w)
                        {
                            m_min=edge[pre[s[now]]].w;
                            id=now-1;
                        }
                        now--;
                    }
                    ans+=m_min;now=tot;
                    while(pre[s[now]])
                    {
                        edge[pre[s[now]]].w-=m_min;
                        edge[pre[s[now]]^1].w+=m_min;
                        now--;
                    }
                    tot=id;
                    used[T]=0;
                }
                else
                {
                    int u=s[tot];
                    for(int i=head[u];i!=-1;i=edge[i].next)
                    {
                        int v=edge[i].to,w=edge[i].w;
                        if(!used[v]&&dep[v]==dep[u]+1&&w)
                        {
                            push(v);
                            pre[v]=i;
                            used[v]=1;
                            break;
                        }
                    }
                    if(s[tot]==u) pop();
                }
            }
        }
        printf("%d
    ",ans);
        return 0;
    }
    
    

    100分:

    #include <cstdio>
    #include <cstring>
    #include <queue>
    using namespace std;
    int min(int x,int y){return x<y?x:y;}
    const int N=2508;
    const int inf=0x3f3f3f3f;
    int C,L,l[N],r[N],T;
    struct Edge
    {
        int next,to,w;
    }edge[N*N];
    int head[N<<2],cnt=-1;
    void add(int u,int v,int w)
    {
        edge[++cnt].next=head[u];edge[cnt].to=v;edge[cnt].w=w;head[u]=cnt;
    }
    int dep[N<<2],s[N<<2],pre[N<<2],used[N<<2],tot=0,ans=0;
    queue <int > q;
    void push(int x){s[++tot]=x;}
    void pop(){tot--;}
    bool bfs()
    {
        memset(dep,0,sizeof(dep));
        while(!q.empty()) q.pop();
        q.push(0);
        dep[0]=1;
        while(!q.empty()&&q.front()!=T)
        {
            int u=q.front();
            q.pop();
            for(int i=head[u];i!=-1;i=edge[i].next)
            {
                int v=edge[i].to,w=edge[i].w;
                if(!dep[v]&&w)
                {
                    dep[v]=dep[u]+1;
                    q.push(v);
                }
            }
        }
        return !q.empty();
    }
    int main()
    {
        scanf("%d%d",&C,&L);
        memset(head,-1,sizeof(head));
        T=C+L+1;
        for(int i=1;i<=C;i++)
        {
            scanf("%d%d",l+i,r+i);
            add(0,i,1),add(i,0,0);
        }
        int num,d;
        for(int i=1;i<=L;i++)
        {
            scanf("%d%d",&d,&num);
            for(int j=1;j<=C;j++)
                if(l[j]<=d&&d<=r[j])
                    add(j,i+C,1),add(i+C,j,0);
            add(i+C,T,num),add(T,i+C,0);
        }
        while(bfs())
        {
            push(0);
            memset(used,0,sizeof(used));
            memset(pre,-1,sizeof(pre));
            while(tot)
            {
                if(s[tot]==T)
                {
                    int now=tot,id,m_min=inf;
                    while(pre[s[now]]!=-1)
                    {
                        if(m_min>=edge[pre[s[now]]].w)
                        {
                            m_min=edge[pre[s[now]]].w;
                            id=now-1;
                        }
                        now--;
                    }
                    ans+=m_min;now=tot;
                    while(pre[s[now]]!=-1)
                    {
                        edge[pre[s[now]]].w-=m_min;
                        edge[pre[s[now]]^1].w+=m_min;
                        now--;
                    }
                    tot=id;
                    used[T]=0;
                }
                else
                {
                    int u=s[tot];
                    for(int i=head[u];i!=-1;i=edge[i].next)
                    {
                        int v=edge[i].to,w=edge[i].w;
                        if(!used[v]&&dep[v]==dep[u]+1&&w)
                        {
                            push(v);
                            pre[v]=i;
                            used[v]=1;
                            break;
                        }
                    }
                    if(s[tot]==u) pop();
                }
            }
        }
        printf("%d
    ",ans);
        return 0;
    }
    
    

    0和-1的锅。。。


    2018.6.8

  • 相关阅读:
    CheckBox单选功能
    DOTNET
    常用命令行
    不能调试的问题的解决
    url字符串中含有中文的处理
    案例:星移eWorkflow.net系统
    使用正则表达式求完整路径中的文件名
    缺少一个***.resource的报告的解决
    Mapx中的图元移动
    Distance计算的距离随经纬度不同
  • 原文地址:https://www.cnblogs.com/butterflydew/p/9157793.html
Copyright © 2011-2022 走看看