hdu3572 Task Schedule(最大流dinic)

来源:互联网 发布:东莞软件外包公司 编辑:程序博客网 时间:2024/05/17 00:59

来自:https://www.2cto.com/kf/201408/326985.html


题解: 网络流建模. 对于每一个任务来说,它必须要在si到ei天之间被处理. 并且要在pi天以内完成. 所以我们可以把每一天当成点来考虑,那么每天就有m个机器在工作,相当于每一天有流量为m的物品流向任务区,每个任务也当成点,那么为了保证每个任务每天只能有一个机器人处理,那我们从就可以从天这些点往任务连边,然后每个任务往汇点t流一条流量为pi的边,同理,汇点s往天数连一条流量为m的边.这样就是跑最大流,看最后是不是满流就可以了.


不知道为什么之前用的那个模板一直超时,大概那个模板不够优秀吧




#include <stdio.h>#include <string.h>#include <iostream>#include <vector>#include <queue>#include <set>#include<map>#include <string>#include <math.h>#include <stdlib.h>#include <time.h>using namespace std; const int MAXN = 1100;const int MAXM = 2e6;const int INF = 0x3f3f3f3f; struct Node{    int u,v,next;    int w;}e[MAXM * 2];int edn;int Head[MAXN];int que[MAXN];int dep[MAXN]; //dep为点的层次int stack[MAXN];//stack为栈,存储当前增广路int cur[MAXN];//存储当前点的后继 void Init(){    edn=0;    memset(Head,-1,sizeof(Head));} void add(int u, int v, int w){    e[edn].u = u;    e[edn].v = v;    e[edn].w = w;    e[edn].next = Head[u];    Head[u] = edn++;    e[edn].u = v;    e[edn].v = u;    e[edn].w = 0;    e[edn].next = Head[v];    Head[v] = edn++;}int BFS(int start, int end){    int front, rear;    front = rear = 0;    memset(dep, -1, sizeof(dep));    que[rear++] = start;    dep[start] = 0;    while (front != rear)    {        int u = que[front++];        if (front == MAXN)front = 0;        for (int i = Head[u]; i != -1; i = e[i].next)        {            int v = e[i].v;            if (e[i].w > 0 && dep[v] == -1)            {                dep[v] = dep[u] + 1;                que[rear++] = v;                if (rear >= MAXN)rear = 0;                if (v == end)return 1;            }        }    }    return 0;}int dinic(int start, int end){    int res = 0;    int top;    while (BFS(start, end)){        memcpy(cur, Head, sizeof(Head));        int u = start;        top= 0;        while (true){            if (u==end){                int min = INF;                int loc;                for (int i = 0; i <top; i++)                    if (min > e[stack[i]].w){                        min = e[stack[i]].w;                        loc = i;                    }                for (int i = 0; i < top; i++){                    e[stack[i]].w -= min;                    e[stack[i] ^ 1].w += min;                }                res += min;                top = loc;                u = e[stack[top]].u;            }            for (int i = cur[u]; i != -1; cur[u] = i = e[i].next)                if (e[i].w != 0 && dep[u] + 1 == dep[e[i].v])                    break;            if (cur[u] != -1){                stack[top++] = cur[u];                u = e[cur[u]].v;            }            else{                if (top==0)break;                dep[u]=-1;                u=e[stack[--top]].u;            }        }    }    return res;}  int main(){    int t,n,m;    int c=1;    scanf("%d",&t);    while(t--){        scanf("%d%d",&n,&m);        Init();        int sp=0;        int tp=1001;        int sum=0;        for(int i=1; i<=n;i++)        {            int p,s,e;            scanf("%d%d%d",&p,&s,&e);            for(int k =s;k<=e;k++)                add(k,500+i,1);            add(500 + i,tp,p);            sum += p;        }        for(int i=1;i<=500;i++)            add(sp,i,m);        if(sum==dinic(sp,tp))printf("Case %d: Yes\n\n",c++);else printf("Case %d: No\n\n",c++);    }    return 0;}


原创粉丝点击