zoukankan      html  css  js  c++  java
  • POJ1698 最大流或者匈牙利

    题意:
          一个人他有n个任务,每个任务都有一些限制:
     (1)只能在一个星期中指定的日子去做,比如周1 2 6啥的
     (2)总工作量有几天,就是一共要工作几天
     (3)必须在几周之内完成,就是你可以在能干活的日子里面选择那天去干活,但是不能超过规定的星期。
    然后问,是否可以不冲突的干完所有的活?


    思路:
          题目一般,没啥难度,做法也很多,说下最大流的做法吧,建图:
    虚拟超级远点 s ,超级汇点t,拆点,把所有天数都拆开,就是第一周的星期1和第二周的星期一不是同一个点。


    s连接所有任务 流量是天数
    任务连接所有满足限制(2)(3)的已经拆开了的天  流量是INF
    所有拆开的天数连接t,流量1.


    然后一边最大流就行了,如果不想最大流可以把每个任务在拆成天数个点,就是比如任务一需要3天完成,那么就把他拆成三个一天的任务,然后建图差不多,一遍二分匹配就行了,时间复杂度肯定允许,如果只是为了AC还有很多别的方法,题目不难,就说这么多吧。






    #include<queue>
    #include<stdio.h>
    #include<string.h>


    #define N_node 20 + 350 + 1 + 5
    #define N_edge (20 * 350 + 20 + 350) * 2 + 100
    #define INF 1000000000


    using namespace std;


    typedef struct
    {
        int x ,t;
    }DEP;


    typedef struct
    {
        int to ,cost ,next;
    }STAR;


    DEP xin ,tou;
    STAR E[N_edge];
    int list[N_node] ,listt[N_node] ,tot;
    int deep[N_node];


    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;
    }


    int minn(int x ,int y)
    {
        return x <y ? x : y;
    }


    bool BFS_Deep(int s ,int t ,int n)
    {
        memset(deep ,255 ,sizeof(deep));
        deep[s] = 0;
        xin.x = s ,xin.t = 0;
        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)
            {
                xin.x = E[k].to;
                xin.t = tou.t + 1;
                if(deep[xin.x] != -1 || !E[k].cost)
                continue;
                deep[xin.x] = xin.t;
                q.push(xin);
            }
        }
        for(int i = 0 ;i <= n ;i ++)
        listt[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 = listt[s] ;k ; k = E[k].next)
        {
            listt[s] = k;
            int to = E[k].to;
            int c = E[k].cost;
            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(nowflow == flow) 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 t ,n ,i ,j ,maxk ,s;
        int tmp[10];
        scanf("%d" ,&t);
        while(t--)
        {
            scanf("%d" ,&n);
            memset(list ,0 ,sizeof(list));
            tot = 1 ,maxk = 0 ,s = 0;
            for(i = 1 ;i <= n ;i ++)
            {
                for(j = 1 ;j <= 9 ;j ++)
                scanf("%d" ,&tmp[j]);
                if(maxk < tmp[9]) maxk = tmp[9];
                s += tmp[8];
                add(0 ,i ,tmp[8]);
                for(j = 1 ;j <= 7 ;j ++)
                if(tmp[j])
                {
                    for(int k = 1 ;k <= tmp[9] ;k ++)
                    add(i ,j + (k-1) * 7 + n ,INF);
                }
            }
            for(i = 1 ;i <= 7 ;i ++)
            for(j = 1 ;j <= maxk ;j ++)
            add((j - 1) * 7 + i + n, maxk * 7 + n + 1 ,1);
            int Flow =  DINIC(0 ,maxk * 7 + n + 1 ,maxk * 7 + n + 1);
            Flow == s ? puts("Yes") : puts("No");
        }
        return 0;


    }





  • 相关阅读:
    谷歌浏览器插件开发Tutorial: Getting Started (Hello, World!) 教程:准备开始(你好,世界!)
    Android ViewPager多页面滑动切换以及动画效果
    4.4 我同意条款—CheckBox的isCheck属性
    4.2设计具有背景图的按钮—ImageButton的焦点及事件处理
    【文件打开】浏览打开窗口
    【原创】PE检测工具
    emu8086注册算法分析及KeyGen实现
    学破解 <一> PE格式之MSDOS MZ header
    学破解 <二> PE格式之IMAGE_NT_HEADERS
    反虚拟机程序测试
  • 原文地址:https://www.cnblogs.com/csnd/p/12062485.html
Copyright © 2011-2022 走看看