hdu 3572最大流

Task Schedule

Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 65536/32768K (Java/Other)
Total Submission(s) : 71   Accepted Submission(s) : 20
Problem Description
Our geometry princess XMM has stoped her study in computational geometry to concentrate on her newly opened factory. Her factory has introduced M new machines in order to process the coming N tasks. For the i-th task, the factory has to start processing it at or after day Si, process it for Pi days, and finish the task before or at day Ei. A machine can only work on one task at a time, and each task can be processed by at most one machine at a time. However, a task can be interrupted and processed on different machines on different days. 
Now she wonders whether he has a feasible schedule to finish all the tasks in time. She turns to you for help.
 

Input
On the first line comes an integer T(T<=20), indicating the number of test cases.

You are given two integer N(N<=500) and M(M<=200) on the first line of each test case. Then on each of next N lines are three integers Pi, Si and Ei (1<=Pi, Si, Ei<=500), which have the meaning described in the description. It is guaranteed that in a feasible schedule every task that can be finished will be done before or at its end day.
 

Output
For each test case, print “Case x: ” first, where x is the case number. If there exists a feasible schedule to finish all the tasks, print “Yes”, otherwise print “No”.

Print a blank line after each test case.
 

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
 

Author
allenlowesy
 

Source
2010 ACM-ICPC Multi-University Training Contest(13)——Host by UESTC
 
刚学ISAP~~~感觉还不是很理解的样子~~
#include <iostream>
#include <cstring>
#include <cstdio>
#include <queue>
#define inf 99999999
using namespace std;
int n,m;
struct node
{
    int u,v;
    int flow;
};
node e[200000];
int first[1000];
int next[200000];
int k,nn;
int sap(int s,int t)
{
    int numh[1000],d[1000],curedges[1000],pre[1000];
    int cur_flow,flow_ans=0,u,tmp,neck,i;
    memset(d,0,sizeof(d));
    memset(numh,0,sizeof(numh));
    memset(pre,-1,sizeof(sizeof(pre)));
    for(i=0;i<=nn;i++)
        curedges[i]=first[i];
    numh[0]=nn+1;
    u=s;
    while(d[t]<nn+1)
    {
        if(u==t)
        {
            cur_flow=inf;
            for(i=s;i!=t;i=e[curedges[i]].v)
            {
                if(cur_flow>e[curedges[i]].flow)
                {
                    neck=i;
                    cur_flow=e[curedges[i]].flow;
                }
            }
            for(i=s;i!=t;i=e[curedges[i]].v)
            {
                tmp=curedges[i];
                e[tmp].flow-=cur_flow;
                e[tmp^1].flow+=cur_flow;
            }
            flow_ans+=cur_flow;
            u=neck;
        }
        for(i=curedges[u];i!=-1;i=next[i])
            if(e[i].flow&&d[u]==d[e[i].v]+1)
                break;
        if(i!=-1)
        {
            curedges[u]=i;
            pre[e[i].v]=u;
            u=e[i].v;
        }
        else
        {
            if(0==--numh[d[u]])
                break;
            curedges[u]=first[u];
            for(tmp=nn+1,i=first[u];i!=-1;i=next[i])
                if(e[i].flow)
                    tmp=min(tmp,d[e[i].v]);
            d[u]=tmp+1;
            ++numh[d[u]];
            if(u!=s)
                u=pre[u];
        }
    }
    return flow_ans;
}
inline void add_edge(int u,int v,int w)
{
    e[k].u=u;
    e[k].v=v;
    e[k].flow=w;
    next[k]=first[u];
    first[u]=k;
    k++;

    e[k].u=v;
    e[k].v=u;
    e[k].flow=0;
    next[k]=first[v];
    first[v]=k;
    k++;
}
int main()
{
    int t,cas;
    scanf("%d",&t);
    for(cas=1;cas<=t;cas++)
    {
        scanf("%d%d",&n,&m);
        int i;
        int day=0;
        memset(first,-1,sizeof(first));
        memset(next,-1,sizeof(next));
        k=0;
        for(i=1;i<=n;i++)
        {
            int pi,si,ei;
            scanf("%d%d%d",&pi,&si,&ei);
            day+=pi;
            add_edge(0,i,pi);
            int j;
            for(j=si;j<=ei;j++)
            {
                add_edge(i,n+j,1);
            }
        }
        nn=n+500+1;
        for(i=n+1;i<=n+500;i++)
            add_edge(i,nn,m);
        if(sap(0,nn)==day)
            printf("Case %d: Yes\n\n", cas);
        else
            printf("Case %d: No\n\n", cas);
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值