hdu3572-Task Schedule(最大流(ISAP),是否满流)

来源:互联网 发布:上海重庆火锅 知乎 编辑:程序博客网 时间:2024/05/16 14:08

题目来源:http://howproblem.php?pid=3572

题意

给出多个任务,起始日期,终止日期,以及每个任务的任务量(一天里一台机器只能做其中一个任务的一点任务量),,问在各自的截止日期前,能不能完成。。所有任务。

思路

这道题目起初做没有头绪。。(菜。。)
但是题目中说每个任务可以由不同的机器完成,这个时候就可以想到一个图,假如,在所有任务前面加一个源点,流量分别是各自的任务量,把每一天都看成一个点,那么各个任务就可以和代表天的点相连,流量均为1,最后,把这些天与汇点相连,流量为机器的数量。。。
如图(样例):
这里写图片描述
这样的话,就可以利用这个图是否满流进而判断能不能完成了。。。

代码

#include<cstdio>#include<cstring>#include<queue>#include<algorithm>using namespace std;const int INF=0x3f3f3f3f;const int maxn=10000+10;int first[maxn],h[maxn],cur[maxn];struct pp{    int v,nexx;    int cap,flow;}edge[1000000+10];int m,n,full_flow,mx;int tot;void ADD(int u,int v,int w){    edge[tot].v=v;    edge[tot].nexx=first[u];    edge[tot].cap=w;    edge[tot].flow=0;    first[u]=tot++;}void init(int cases){    full_flow=tot=mx=0;    scanf("%d%d",&m,&n);    memset(first,-1,sizeof(first));    for(int i=1;i<=m;i++)    {        int time,st,ed;        scanf("%d%d%d",&time,&st,&ed);        full_flow+=time;        mx=max(mx,ed);        ADD(0,i,time);        ADD(i,0,0);        for(int j=st;j<=ed;j++)        {            ADD(i,m+j,1);            ADD(m+j,i,0);        }    }    for(int i=1;i<=mx;i++)    {        ADD(m+i,m+mx+1,n);        ADD(m+mx+1,m+i,0);    }    printf("Case %d: ",cases);}int num[maxn];void height(int s,int t){    queue<int> Q;    memset(num,0,sizeof(num));    memset(h,-1,sizeof(h));    h[t]=0;    ++num[0];    while(!Q.empty()) Q.pop();    Q.push(t);    while(!Q.empty())    {        int v=Q.front();        Q.pop();        for(int i=first[v];~i;i=edge[i].nexx)        {            int u=edge[i].v;            if(h[u]==-1)            {                h[u]=h[v]+1;                ++num[h[u]];                Q.push(u);            }        }    }}int S[maxn];void print_ISAP(int s,int t,int node){    int top=0,ans=0,u=s;    memcpy(cur,first,sizeof(first));    while(h[s]<node)    {        if(u==t)        {            int d=INF,pos;            for(int i=0;i<top;i++)            {                if(d>edge[S[i]].cap-edge[S[i]].flow)                {                    d=edge[S[i]].cap-edge[S[i]].flow;                    pos=i;                }            }            for(int i=0;i<top;i++)            {                edge[S[i]].flow+=d;                edge[S[i]^1].flow-=d;            }            ans+=d;            top=pos;            u=edge[S[top]^1].v;            continue;        }        int i=cur[u];        for(;~i;i=edge[i].nexx)        {            int v=edge[i].v;            if(h[u]==h[v]+1&&edge[i].cap>edge[i].flow)            {                cur[u]=i;                S[top++]=i;                u=v;                break;            }        }        if(i==-1)        {            int d=node;//点的个数            for(int i=first[u];~i;i=edge[i].nexx)            {                if(edge[i].cap>edge[i].flow&&d>h[edge[i].v])                {                    d=h[edge[i].v];                    cur[u]=i;                }            }            if(--num[h[u]]==0) break;            h[u]=d+1;            ++num[h[u]];            if(u!=s)                u=edge[S[--top]^1].v;        }    }    if(ans==full_flow)        printf("Yes\n\n");    else        printf("No\n\n");}int main(){    int T;    scanf("%d",&T);    for(int i=1;i<=T;i++)    {        init(i);        height(0,m+mx+1);        print_ISAP(0,m+mx+1,m+mx+2);    }    return 0;}
原创粉丝点击