HDOJ-3572 Task Schedule(网络流)

来源:互联网 发布:mplayer移植arm linux 编辑:程序博客网 时间:2024/05/16 23:53

题意:

有 N(N<=500)个任务..有M(<=200)个机器。第i个任务要在大于等于第Si天开始做,小于等于Ei天完成。.第i个任务要做Pi天。每个任务不一定要连续的做,即在[Si,Ei]间做满Pi天即可。每个机器每天只能完成一个任务一天的工作量。每个任务每次只能被一台机器做。问每个任务是否都能按时完成。


做法:

建图如下:设超级源点1,到每个任务点之间的容量为Pi,每个任务点到第Si至Ei天都建一条边,容量为1。每一天到超级汇点建边,容量为m。跑一遍最大流,如果超级源点与超级汇点之间的最大流等于P之和,则可以按时完成任务。(可以这么理解:把每个任务分配到每一个在区间内的天,但是每一天做多能接收m个任务)


代码:

#include <cstdio>#include <cstdlib>#include <cstring>#include <algorithm>using namespace std;const int MAXN=200005;const int MAXE=400005;const int INF=0X3F3F3F3F;struct Edge{  int to,next,cap,flow; }edge[MAXE];int tol;int head[MAXN];int gap[MAXN],dep[MAXN],pre[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].next=head[u];    edge[tol].flow=0;    head[u]=tol++;    edge[tol].to=u;    edge[tol].cap=rw;    edge[tol].next=head[v];    edge[tol].flow=0;    head[v]=tol++;}int sap(int start,int end,int N){    memset(gap,0,sizeof(gap));    memset(dep,0,sizeof(dep));    memcpy(cur,head,sizeof(head));    int u=start;    pre[u]=-1;    gap[0]=N;    int ans=0;    while(dep[start]<N)    {        if(u==end)        {            int Min=INF;            for(int i=pre[u];i!=-1;i=pre[edge[i^1].to])            {                if(Min>edge[i].cap-edge[i].flow)                    Min=edge[i].cap-edge[i].flow;            }            for(int i=pre[u];i!=-1;i=pre[edge[i^1].to])            {                edge[i].flow+=Min;                edge[i^1].flow-=Min;            }            u=start;            ans+=Min;            continue;        }        bool flag=false;        int v;        for(int 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]=pre[v]=i;                break;            }        }        if(flag)        {            u=v;            continue;        }        int Min=N;        for(int 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[pre[u]^1].to;    }    return ans;}void work(){    int i,j,n,m,x,s,e,p,sum,sump;    scanf("%d%d",&n,&m);    sum=0;    sump=0;    init();    for(i=1;i<=n;i++)    {        scanf("%d%d%d",&p,&s,&e);        sum=max(sum,e);        sump+=p;        addedge(1,i+1,p);        for(j=s;j<=e;j++)            addedge(i+1,1+n+j,1);    }    for(i=1;i<=sum;i++)       addedge(1+n+i,2+n+sum,m);        if(sump==sap(1,2+n+sum,2+n+sum))        printf("Yes\n");    else printf("No\n");        }int main(){    int i,T;    scanf("%d",&T);    for(i=1;i<=T;i++)    {        printf("Case %d: ",i);        work();        printf("\n");    }    return 0;}


0 0
原创粉丝点击