hdu 3527 Task Schedule 最大流 Dinic

Task Schedule

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 5707    Accepted Submission(s): 1840


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
 

Recommend
zhouzeyong   |   We have carefully selected several similar problems for you:   3491  1533  3416  3081  3338 


充分利用 网络流的流量限制cap来建图,其中包括这些点:源点S,汇点E,n个工作点,每一天(到底多少天要自己算)。
首先建立源点S,对于每个工作i,S与i相连,cap=工作所需天数,反向弧cap=0;
对于每个工作i,都有相应能做这个工作个日期 ,将i与其对应的所有日期相连,容量cap为1;
建立汇点E,将每一天与汇点E相连,容量为m(机器数)。

读入数据的时候,统计所有工作量之和。
跑一次最大流算法,看流量是否等于 所有工作量之和,是的Yes,否则No。

#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<climits>
#include<queue>
#include<vector>
#include<map>
#include<sstream>
#include<set>
#include<stack>
#include<utility>
#pragma comment(linker, "/STACK:102400000,102400000")
#define PI 3.1415926535897932384626
#define eps 1e-10
#define sqr(x) ((x)*(x))
#define FOR0(i,n)  for(int i=0 ;i<(n) ;i++)
#define FOR1(i,n)  for(int i=1 ;i<=(n) ;i++)
#define FORD(i,n)  for(int i=(n) ;i>=0 ;i--)
#define  lson   num<<1,le,mid
#define rson    num<<1|1,mid+1,ri
#define MID   int mid=(le+ri)>>1
#define zero(x)((x>0? x:-x)<1e-15)
#define mk    make_pair
#define _f     first
#define _s     second

using namespace std;
const int INF =0x3f3f3f3f;
const int maxn= 1020   ;
const int maxm= 2*( 505*505+1000)  ;
//const int INF=    ;
typedef long long ll;
const ll inf =1000000000000000;//1e15;
//ifstream fin("input.txt");
//ofstream fout("output.txt");
//fin.close();
//fout.close();
//freopen("a.in","r",stdin);
//freopen("a.out","w",stdout);
//by yskysker123

struct Edge
{
    int from,to,cap,flow;
    Edge(){}
    Edge(int f,int t,int c,int fl):from(f),to(t),cap(c),flow(fl){}
}  ;
vector<Edge> edges;
vector<int >G[maxn];
void add_edge(int s,int t,int cap)
{
    edges.push_back(Edge(s,t,cap,0  ));
    edges.push_back(Edge(t,s,0,0  ));
    int m=edges.size();
    G[s].push_back(m-2);
    G[t].push_back(m-1);
}
int n,m,S,E,cur[maxn],d[maxn];
bool vis[maxn];

bool bfs()
{
    memset(vis,0,sizeof vis);
    queue<int >q;
    q.push(S);
    d[S]=0;vis[S]=1;
    while(!q.empty())
    {
        int x=q.front();q.pop();
        for(int i=0;i<G[x].size();i++)
        {
            Edge& e=edges[G[x][i]];
            if(vis[e.to]||e.cap-e.flow<=0) continue;
            vis[e.to]=1;
            d[e.to]=d[x]+1;
            q.push(e.to);
        }
    }
    return vis[E];
}

int dfs(int x,int a)
{
    if(x==E||a==0)  return a;
    int flow=0,f;
    for(int &i=cur[x];i<G[x].size();i++)
    {
        Edge & e=edges[G[x][i]];
        if(d[x]+1!=d[e.to]||(f=dfs( e.to,min(a, e.cap-e.flow )  ))<=0 )  continue;
        e.flow+=f;
        edges[ 1^G[x][i]  ].flow-=f;
        flow+=f;
        a-=f;
        if(a==0)  break;
    }
    return flow;
}
int maxflow()
{
    int flow=0;
    while(bfs())
    {
        memset(cur,0,sizeof cur);
        flow+=dfs(S,INF);
    }
    return flow;
}

inline void init()
{
    for(int i=S;i<= n+501;i++  )
        G[i].clear();
    edges.clear();
}
int main()
{
    int T,time,st,ed,last,kase=0;scanf("%d",&T);
    while(T--)
    {
        int prin=0;
        scanf("%d%d",&n,&m);
         S=0;
        init();
       last=0;
        for(int i=1;i<=n;i++)
        {
             scanf("%d%d%d",&time,&st,&ed);
             prin+=time;
             last=max(last,ed);
             add_edge(S,i,time);
             for(int j=st;j<=ed;j++)
                add_edge(i,n+j,1);
        }
        E=last+n+1;
        for(int i=1;i<=last;i++)
            add_edge(n+i,E ,m  );
            printf("Case %d: ",++kase);
        int ans=maxflow();
        if(ans==prin )   puts("Yes\n");
        else puts("No\n");





    }

    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值