• POJ3614奶牛晒阳光DINIC或者贪心


    题意:
          n个区间,m种点,每种点有ci个,如果一个点的范围在一个区间上,那么就可以消耗掉一个区间,问最多可以消耗多少个区间,就是这n个区间中,有多少个可能被抵消掉。


    思路:
          方法不唯一,首先可以用贪心来做,看到网上说的都是优先队列的解法,我说下我的想法,我是直接sort排序后暴力(其实根本达不到n*m*l的时间复杂度),我先把所有老牛也就是区间按照上端点(***不是他们说的下端点)从小打到排序,然后在把护肤品按照第一个值从小到大排序,然后就是给给每一个护肤品尽可能找到一个点,同时这个点的右端点尽可能的小,为了后面别的护肤品留下更大的机会,下面分析枚举代码
    第i个护肤品的第j个和第k只奶牛


    for(i = 1 ;i <= m ;i ++)
    for(j = 1 ;j <= sp[i].c ;j ++)
    {
        for(k = 1 ;k <= n ;k ++)
        if(!mark[k] && cow[k].l <= sp[i].p && cow[k].r >= sp[i].p)
        {
              ans ++;
              mark[k] = 1;
              break;  
        }
        if(k == n + 1) 我个人觉得我加的这个地方可以很好的优化掉很多数据,这么加的
        break;         依据是如果第i种护肤品的第j个不能给剩下的奶牛用了,那么第i种
    }                  的其他的也没用了,直接break




    还有就是这个题目可以最大流来做,至于用那种算法,自己随意吧,我用的是DINC,建图比较简单,我不想说了,如果你做过流的话一下就能想到建图了,其实我感觉这个题目用最大流有点悬,但是AC了,因为边的条数可能达到 (2500*2500+5000)* 2 = 12510000。

    贪心
    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    
    #define N 2500 + 10
    
    using namespace std;
    
    typedef struct
    {
        int l ,r;
    }COW;
    
    typedef struct
    {
        int p ,c;
    }SP;
    
    COW cow[N];
    SP sp[N];
    int mark[N];
    
    bool camp1(COW a ,COW b)
    {
        return  a.r < b.r;
    }
    
    bool camp2(SP a ,SP b)
    {
        return a.p < b.p;
    }
    
    int main ()
    {
        int n ,m, i ,j ,k;
        while(~scanf("%d %d" ,&n ,&m))
        {
            for(i = 1 ;i <= n ;i ++)
            scanf("%d %d" ,&cow[i].l ,&cow[i].r);
            for(i = 1 ;i <= m ;i ++)
            scanf("%d %d" ,&sp[i].p ,&sp[i].c);
            sort(cow + 1 ,cow + n + 1 ,camp1);
            sort(sp + 1 ,sp + m + 1 ,camp2);
    
            memset(mark ,0 ,sizeof(mark));
            int ans = 0;
            for(i = 1 ;i <= m ;i ++)
            for(j = 1 ;j <= sp[i].c ;j ++)
            {
                for(k = 1 ;k <= n ;k ++)
                if(!mark[k] && cow[k].l <= sp[i].p && cow[k].r >= sp[i].p)
                {
                    ans ++;
                    mark[k] = 1;
                    break;
                }
                if(k == n + 1)
                break;
            }
            printf("%d
    " ,ans);
        }
        return 0;
    }
    
    
    DINIC
    
    #include<queue>
    #include<stdio.h>
    #include<string.h>
    
    #define N_node 2500 + 10
    #define N_edge (2500 * 2500 + 5000) * 2 + 100
    #define INF 1000000000
    
    using namespace std;
    
    typedef struct
    {
        int to ,cost ,next;
    }STAR;
    
    typedef struct
    {
        int x ,t;
    }DEP;
    
    typedef struct
    {
        int l ,r;
    }COW;
    
    typedef struct
    {
        int p ,c;
    }SP;
    
    
    COW cow[N_node];
    SP sp[N_node];
    STAR E[N_edge];
    int list[N_node] ,list2[N_node] ,tot;
    int deep[N_node];
    DEP xin ,tou;
    
    int minn(int x ,int y)
    {
        return x < y ? x : y;
    }
    
    void add(int a ,int b ,int c)
    {
        E[++tot].to = b;
        E[tot].cost = c;
        E[tot].next = list[a];
        list[a] = tot;
    
        E[++tot].to = a;
        E[tot].cost = 0;
        E[tot].next = list[b];
        list[b] = tot;
    }
    
    bool BFS_Deep(int s ,int t ,int n)
    {
        memset(deep ,255 ,sizeof(deep));
        xin.x = s ,xin.t = 0;
        deep[xin.x] = xin.t;
        queue<DEP>q;
        q.push(xin);
        while(!q.empty())
        {
            tou = q.front();
            q.pop();
            for(int k = list[tou.x] ;k ;k = E[k].next)
            {
                int to = E[k].to;
                if(deep[to] != -1 || !E[k].cost)
                continue;
                xin.x = to ,xin.t = tou.t + 1;
                deep[xin.x] = xin.t;
                q.push(xin);
            }
        }
        for(int i = 0 ;i <= n ;i ++)
        list2[i] = list[i];
        return deep[t] != -1;
    }
    
    int DFS_Flow(int s ,int t ,int flow)
    {
        if(s == t) return flow;
        int nowflow = 0;
        for(int k = list2[s] ;k ;k = E[k].next)
        {
            int to = E[k].to;
            int c = E[k].cost;
            list2[s] = k;
            if(deep[to] != deep[s] + 1 || !c)
            continue;
            int tmp = DFS_Flow(to ,t ,minn(c ,flow - nowflow));
            nowflow += tmp;
            E[k].cost -= tmp;
            E[k^1].cost += tmp;
            if(flow == nowflow) break;
        }
        if(!nowflow) deep[s] = 0;
        return nowflow;
    }
    
    int DINIC(int s ,int t ,int n)
    {
        int ans = 0;
        while(BFS_Deep(s ,t ,n))
        {
            ans += DFS_Flow(s ,t ,INF);
        }
        return ans;
    }
    
    int main ()
    {
        int n ,m, i ,j;
        while(~scanf("%d %d" ,&n ,&m))
        {
            memset(list ,0 ,sizeof(list));
            tot = 1;
            for(i = 1 ;i <= n ;i ++)
            {
                scanf("%d %d" ,&cow[i].l ,&cow[i].r);
                add(0 ,i ,1);
            }
            for(i = 1 ;i <= m ;i ++)
            {
                scanf("%d %d" ,&sp[i].p ,&sp[i].c);
                add(i + n ,m + n + 1 ,sp[i].c);
            }
    
            for(i = 1 ;i <= n ;i ++)
            for(j = 1 ;j <= m ;j ++)
            if(cow[i].l <= sp[j].p && cow[i].r >= sp[j].p)
            add(i ,j + n ,1);
    
            printf("%d
    " ,DINIC(0 ,n + m + 1 ,n + m + 1));
        }
        return 0;
    
    }
    
    
    



  • 相关阅读:
    如何最大限度提高.NET的性能
    Webserivce简单安全验证
    一些NLP相关的JD,作参考
    拼多多的故事
    storm的一些相关文章
    这篇文章不错,仔细读读,码农晋升为技术管理者后,痛并快乐着的纠结内心
    protobuf的反射机制
    如何清理Docker占用的磁盘空间?
    经典面试题:浏览器是怎样解析CSS的?
    代码编辑器横评:为什么 VS Code 能拔得头筹
  • 原文地址:https://www.cnblogs.com/csnd/p/12062437.html
Copyright © 2020-2023  润新知