【最大流】 HDU 3572 Task Schedule

来源:互联网 发布:查找表格中相同数据 编辑:程序博客网 时间:2024/04/30 06:38

题意 给出N个任务和M台机器

任务中给出 C  S E 分别表示 所需时间  任务开始时间  任务结束时间 

即任务需要在开始到结束这时间段中完成。

一个任务可以在不同的机器上完成,但每次在机器上至少要运行一天

建边, 源点-任务 容量为C

   任务-时间段上的每一个时间点 容量为1 

   时间点-汇点 容量为 M

最大流 >= sigma(C)则YES else NO

(最大所需点数为n+m+2;)

#include <stdio.h>#include <string.h>#include <stdlib.h>#include <string>#include <iostream>#include <algorithm>#include <sstream>#include <math.h>using namespace std;#include <queue>#include <stack>#include <vector>#include <deque>#include <set>#include <map>#include <time.h>;#define cler(arr, val)    memset(arr, val, sizeof(arr))#define IN     freopen ("in.txt" , "r" , stdin);#define OUT  freopen ("out.txt" , "w" , stdout);typedef long long  LL;const int MAXN = 200010;//点数的最大值const int MAXM = 200006;//边数的最大值const int INF = 0x3f3f3f3f;const int mod = 10000007;struct Edge{    int to,next,cap,flow;}edge[MAXM];//注意是MAXMint tol;int head[MAXN];int gap[MAXN],dep[MAXN],cur[MAXN];void init(){    tol = 0;    memset(head,-1,sizeof (head));}void addedge (int u,int v,int w,int rw = 0){    edge[tol].to = v; edge[tol].cap = w; edge[tol].flow = 0;    edge[tol].next = head[u]; head[u] = tol++;    edge[tol].to = u; edge[tol].cap = rw; edge[tol].flow = 0;    edge[tol].next = head[v]; head[v] = tol++;}int Q[MAXN];void BFS(int start,int end){    memset(dep,-1,sizeof(dep));    memset(gap,0,sizeof(gap));    gap[0] = 1;    int front = 0, rear = 0;    dep[end] = 0;    Q[rear++] = end;    while(front != rear)    {        int u = Q[front++];        for(int i = head[u]; i !=  -1; i = edge[i].next)        {            int v = edge[i]. to;            if(dep[v] != -1)continue;            Q[rear++] = v;            dep[v] = dep[u] + 1;            gap[dep[v]]++;        }    }}int S[MAXN];int sap(int start,int end, int N){    BFS(start,end);    memcpy(cur,head,sizeof(head));    int top = 0;    int u = start;    int ans = 0;    int i;    while(dep[start] < N)    {        if(u == end)        {            int Min = INF;            int inser;            for( i = 0;i < top;i++)            {                if(Min > edge[S[i]].cap - edge[S[i]].flow)                {                    Min = edge[S[i]].cap - edge[S[i]].flow;                    inser = i;                }            }            for( i = 0;i < top;i++)            {                edge[S[i]]. flow += Min;                edge[S[i]^1].flow -= Min;            }            ans += Min;            top = inser;            u = edge[S[top]^1].to;            continue;        }        bool flag =  false;        int v;        for( i = cur[u]; i != -1; i = edge[i]. next)        {            v = edge[i]. to;            if(edge[i].cap - edge[i].flow && dep[v]+1 == dep[u])            {                flag =  true;                cur[u] = i;                break;            }        }        if(flag)        {            S[top++] = cur[u];            u = v;            continue;        }        int Min = N;        for( i = head[u]; i !=  -1; i = edge[i].next)        {            if(edge[i].cap - edge[i].flow && dep[edge[i].to] < Min)            {                Min = dep[edge[i].to];                cur[u] = i;            }        }        gap[dep[u]]--;        if(!gap[dep[u]]) return ans;        dep[u] = Min + 1;        gap[dep[u]]++;        if(u != start)u = edge[S[--top]^1].to;    }    return ans;}int main(){    //IN;    int t,cas=0,m,n;    scanf("%d",&t);    while(t--)    {        init();        scanf("%d %d",&n,&m);        int e=500+n+1,sum=0;        for(int i=1;i<=500;i++)        {            addedge(n+i,e,m);        }        for(int i=1;i<=n;i++)        {            int x,y,c;            scanf("%d %d %d",&c,&x,&y);            sum+=c;            addedge(0,i,c);//源点到任务            for(int j=x;j<=y;j++)//任务到天            {                addedge(i,n+j,1);            }        }        printf("Case %d: ",++cas);        int out=sap(0,e,n+500+2);      //  printf("%d\n",out);        if(out>=sum)            puts("Yes");        else puts("No");        puts("");    }}


0 0
原创粉丝点击