HDU 3572最大流+数组开小会TLE

Posted tennant

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU 3572最大流+数组开小会TLE相关的知识,希望对你有一定的参考价值。

题意:有M个机器,有N个任务。每个任务必须在Si 或者以后开始做,在Ei 或者之前完成,完成任务必须处理Pi 个时间单位。其中,每个任务可以在任意(空闲)机器上工作,每个机器的同一时刻只能工作一个任务,每个任务在同一时刻只能被一个机器工作,而且任务做到一半可以打断,拿去其他机器做。能否在规定时间内把任务做完。

这个题建图简直是经典。。刚开始看也是一脸懵逼,还想用贪心搞一搞。。但素感觉做不出来。
正确的思路是用网络流最大流。
S与每个任务连边,容量为p,每个任务与相应的时间段连边,容量为1,每个时间点与T连边,容量为M。
是不是很巧妙,一看就懂,但完全想不出来

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

以上是关于HDU 3572最大流+数组开小会TLE的主要内容,如果未能解决你的问题,请参考以下文章

HDU 3572 最大流

HDU3572 Task Schedule 最大流

hdu 3572 仪器与任务 最大流 好题 体会建图思想

HDU3572_Task Schedule(网络流最大流)

HDU 3572 Task Schedule(拆点+最大流dinic)

HDU 3572 Task Schedule(最大流判断满流)