POJ1698 最大流或者匈牙利
阅读原文时间:2023年07月08日阅读:3

**题意:

      一个人他有n个任务,每个任务都有一些限制:

 (1)只能在一个星期中指定的日子去做,比如周1 2 6啥的

 (2)总工作量有几天,就是一共要工作几天

 (3)必须在几周之内完成,就是你可以在能干活的日子里面选择那天去干活,但是不能超过规定的星期。

然后问,是否可以不冲突的干完所有的活?

思路:

      题目一般,没啥难度,做法也很多,说下最大流的做法吧,建图:

虚拟超级远点 s ,超级汇点t,拆点,把所有天数都拆开,就是第一周的星期1和第二周的星期一不是同一个点。

s连接所有任务 流量是天数

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

所有拆开的天数连接t,流量1.

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

#include

#include

#include

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

    queueq;

    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;

}

**

手机扫一扫

移动阅读更方便

阿里云服务器
腾讯云服务器
七牛云服务器

你可能感兴趣的文章