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

原文地址:https://www.cnblogs.com/tennant/p/8979338.html

时间: 2024-11-09 05:32:45

HDU 3572【最大流+数组开小会TLE】的相关文章

之前就写好了,but……数组开小了……!!!

#include <iostream> #include <cstdio> #include <cmath> #include <cstring> #include <algorithm> #include <cstdlib> #include <stack> #include <cctype> #include <string> #include <malloc.h> #include

HDU 3572 最大流

[题意]有n个任务,每个任务必须开始于第Si天之后(包括Si),结束于第Ei天之前(包括Ei),每个任务持续的时间为Pi,现在有m台机器,每台每天只能专注做其中一件任务,每个任务做的时间可以不连续.问是否存在一种方案使得这n个任务顺利完成 [类型]最大流 [建图]设一个源点S,将每个任务分别化成一个点,S向每个任务连一条边,容量为Pi,接着每个任务向时间Si~Ei分别连一条容量为1的边,每个时间向汇点连一条容量为m的边.这样跑最大流即可. #include<cstdio> #include&l

8/2 multi4 E找规律+模拟,空间开小了然后一直WA。。。J爆搜check不严谨WA。。。multi3 G凸包判共线写错数组名???样例太好过.想哭jpg。

multi4 Problem E. Matrix from Arrays 题意:构造一个数组,求子矩阵前缀和. 思路:打表找规律,"发现"L为奇数时循环节为L,为偶数时循环节为2L,求相应循环节的二维前缀和然后加加减减计算一下就好. 虚伪地证明一下循环节:L为奇数时对于第x行/列开始的位置有(x  +  x+L-1)*L/2   ->     (2x+L-1)/2(为整数)*L,因此扫过L行/列也就扫过了L整数倍"(2x+L-1)/2"倍的A[0]~A[L],

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

Task Schedule Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 7753    Accepted Submission(s): 2381 Problem Description Our geometry princess XMM has stoped her study in computational geometry t

HDU 3572 Task Schedule (最大流)

C - Task Schedule Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Status Practice HDU 3572 Description Our geometry princess XMM has stoped her study in computational geometry to concentrate on her newly opened fac

hdu 3572 Task Schedule(最大流)

hdu 3572 Task Schedule Description Our geometry princess XMM has stoped her study in computational geometry to concentrate on her newly opened factory. Her factory has introduced M new machines in order to process the coming N tasks. For the i-th tas

HDU 3572 Task Schedule(ISAP)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3572 题意:m台机器,需要做n个任务.第i个任务,你需要使用机器Pi天,且这个任务要在[Si  ,  Ei]区间内完成才有效.对于一个任务,只能由一个机器来完成,一个机器同一时间只能做一个任务.当然,一个任务可以分成几段不连续的时间来完成.问,能否做完全部任务. 题意很清晰,也就是判断是否是满流. 对于网络流问题,模板大家都有,关键在于如何建图(详见资料) 思路:今天问了龙哥,对建图有了一定的了解,

HDU 1394 树状数组(逆序数)

Minimum Inversion Number Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 10100    Accepted Submission(s): 6192 Problem Description The inversion number of a given number sequence a1, a2, ..., an

[ACM] Color the ball [线段树水题][数组开大]

Description N个气球排成一排,从左到右依次编号为1,2,3....N.每次给定2个整数a b(a <= b),lele便为骑上他的"小飞鸽"牌电动车从气球a开始到气球b依次给每个气球涂一次颜色.但是N次以后lele已经忘记了第I个气球已经涂过几次颜色了,你能帮他算出每个气球被涂过几次颜色吗? Input 每个测试实例第一行为一个整数N,(N <= 100000).接下来的N行,每行包括2个整数a b(1 <= a <= b <= N).  当N