HDU 3572 Task Schedule(最大流-Dinic)

来源:互联网 发布:php开发的大型网站 编辑:程序博客网 时间:2024/05/16 14:33

Description
有M个机器,有N个任务。每个任务必须在Si或者以后开始做,在Ei或者之前完成,完成任务必须处理Pi个时间单位。其中,每个任务可以在任意(空闲)机器上工作,每个机器的同一时刻只能工作一个任务,每个任务在同一时刻只能被一个机器工作,而且任务做到一半可以打断,拿去其他机器做。问能否在规定时间内把任务做完
Input
第一行为一个整数T表示用例组数,每组用例第一行两个整数N和M分别表示任务数和机器数,之后N行第i行三个整数Si,Ei,Pi分别表示第i个任务的开始时间下限,结束时间上限与完成该任务需要的时间
Output
对于每组用例,如果能在规定时间将所有任务做完则输出Yes,否则输出No,每组输出后跟一空行
Sample Input
2
4 3
1 3 5
1 1 4
2 3 7
3 5 9

2 2
2 1 3
1 2 2
Sample Output
Case 1: Yes

Case 2: Yes

Solution
最大流问题,将每个任务以及每个时刻都看作节点,源点向每个任务建容量为Pi的边,每个时刻向汇点建容量为M的边,每个任务向在Si与Ei范围内的所有时刻建容量为1的边,之后用Dinic算法判断是否满流即可
Code

#include<cstdio>#include<iostream>#include<cstring>#include<queue>using namespace std;#define maxn 1111#define maxm 555555#define INF 0x3f3f3f3fint head[maxn],cur[maxn],d[maxn],st[maxm],s,e,no,n;struct point{    int u,v,flow,next;    point(){};    point(int x,int y,int z,int w):u(x),v(y),next(z),flow(w){};}p[maxm];void add(int x,int y,int z){    p[no]=point(x,y,head[x],z);     head[x]=no++;    p[no]=point(y,x,head[y],0);     head[y]=no++;}void init(){    memset(head,-1,sizeof(head));    no=0;}bool bfs(){    int i,x,y;    queue<int>q;    memset(d,-1,sizeof(d));    d[s]=0;     q.push(s);    while(!q.empty())    {        x=q.front();            q.pop();        for(i=head[x];i!=-1;i=p[i].next)        {            if(p[i].flow&& d[y = p[i].v]<0)            {                d[y]=d[x]+1;                if(y==e)                        return true;                q.push(y);            }        }    }    return false;}int dinic(){    int i,loc,top,x=s,nowflow,maxflow=0;    while(bfs()){        for(i=s;i<=e;i++)               cur[i]=head[i];        top=0;        while(true)        {            if(x==e)            {                nowflow=INF;                for(i=0;i<top;i++)                {                    if(nowflow>p[st[i]].flow)                    {                        nowflow=p[st[i]].flow;                        loc=i;                    }                }                for(i=0;i<top;i++)                {                    p[st[i]].flow-=nowflow;                    p[st[i]^1].flow+=nowflow;                }                maxflow+=nowflow;                top=loc;                    x=p[st[top]].u;            }            for(i=cur[x];i!=-1;i=p[i].next)                if(p[i].flow&&d[p[i].v]==d[x]+1)                     break;            cur[x]=i;            if(i!=-1)            {                st[top++]=i;                x=p[i].v;            }            else             {                if(!top)                        break;                d[x]=-1;                x=p[st[--top]].u;            }        }    }    return maxflow;}int N,M;int main(){    int T;    scanf("%d",&T);    int res=1;    while(T--)    {        init();//初始化         scanf("%d%d",&N,&M);        s=0;//源点为0         e=N+500+1;//汇点为N+500+1(因为最多有500个时刻)         n=N+500;                int sum=0;        for(int i=1;i<=N;i++)        {            int pi,si,ei;            scanf("%d%d%d",&pi,&si,&ei);            sum+=pi;            add(s,i,pi);//源点向每个任务建容量为pi的边             for(int j=si;j<=ei;j++)//每个任务向si到ei间所有时刻建容量为1的边                 add(i,j+N,1);        }        for(int i=1;i<=500;i++)//每个时刻向汇点建容量为M的边             add(i+N,e,M);        printf("Case %d: ",res++);        if(dinic()==sum)//判断是否满流             printf("Yes\n\n");        else            printf("No\n\n");    }    return 0;} 
0 0
原创粉丝点击