HDU 3572 [maximum stream + array small meeting TLE]

Question: There are M machines and N tasks. Each task must be started at Si or later and completed at or before Ei, and the completion of the task must process Pi time units. Among them, each task can work on any (idle) machine, each machine can only work on one task at the same time, each task can only be worked by one machine at the same time, and the task can be interrupted halfway, take Go to another machine to do it. Can the task be completed within the specified time.

This title is simply a classic. . At first, I was confused, and I wanted to do it with greed. . But I feel like I can't do it.
The correct idea is to use the maximum flow of network flow.
S is connected to each task with a capacity of p, each task is connected to a corresponding time period with a capacity of 1, and each time point is connected to T with a capacity of M.
Is it very clever, I can understand it at a glance, but I can't think of it at all

#include<stdio.h>
#include<string.h>
#include<queue>
#include<iostream>
#define MAX 510000
#define INF 0x3f3f3f3f
using namespace std;
int ss, tt;
int kase;
int sum;
int n, m;
int cont;
int head[MAX];
int divv[MAX];
int cur[MAX];
struct edge {
    int from, to, w, next;

}e[MAX];

void add(int u, int v, int w) {
    e[cont].from = u;
    e[cont].to = v;
    e[cont].w = w;
    e[cont].next = head[u];
    head[u] = cont++;
}



int makediv() {
    memset(divv, 0, sizeof(divv));
    divv[ss] = 1;
    queue<int> Q;
    Q.push(ss);
    while (!Q.empty()) {
        int u = Q.front();
        if (u == tt)
            return 1;
        Q.pop();
        for (int i = head[u]; i != -1; i = e[i].next) {
            int w = e[i].w;
            int v = e[i].to;
            if (divv[v] == 0 && w) {
                divv[v] = divv[u] + 1;
                Q.push(v);
            }
        }

    }
    return 0;

}

int DFS(int u, int maxflow, int tt) {
    if (u == tt)
        return maxflow;
    int ret = 0;
    for (int &i = cur[u]; i != -1; i = e[i].next) {
        int v = e[i].to;
        int w = e[i].w;
        if (divv[v] == divv[u] + 1 && w) {
            int f = DFS(v, min(maxflow - ret, w), tt);
            e[i].w -= f;
            e[i ^ 1].w += f;
            ret += f;
            if (ret == maxflow)
                return ret;

        }
    }
    if (ret)
        return ret;
    else {
        divv[u] = 0;
        return 0;

    }
}

void Dinic() {
    int ans = 0;

    while (makediv() == 1) {
        memcpy(cur, head, sizeof(head));
        ans += DFS(ss, INF, tt);
    }

    if (ans == sum)
        printf("Case %d: Yes\n\n", ++kase);
    else
        printf("Case %d: No\n\n", ++kase);


}


int main(void) {
    int t;
    scanf("%d", &t);
    kase = 0;
    while (t--) {
        sum = 0;
        ss = 0;
        cont = 0;
        memset(head, -1, sizeof(head));
        scanf("%d%d", &n, &m);
        int maxx = 0;
        tt = 500 + n + 2;
        int p, s, e;
        for (int i = 1; i <= n; i++) {
            scanf("%d%d%d", &p, &s, &e);
            sum += p;
            if (e > maxx)
                maxx = e;
            add(ss, i + 500, p);
            add(i + 500, ss, 0);
            for (int j = s; j <= e; j++) {
                add(i + 500, j, 1);
                add(j, i + 500, 0);
            }

        }
        for (int i = 1; i <= maxx; i++) {
            add(i, tt, m);
            add(tt, i, 0);
        }
        Dinic();

    }
    return 0;
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325154461&siteId=291194637