hdu 3572 Task Schedule (Dinic模板)

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

给N个任务,M台机器。每个任务有最早才能开始做的时间S,deadline E,和持续工作的时间P。每个任务可以分段进行,但是在同一时刻,一台机器最多只能执行一个任务. 问存不存在可行的工作时间。

由于时间<=500且每个任务都能断断续续的执行,那么我们把每一天时间作为一个节点来用网络流解决该题.
建图: 源点s(编号0), 时间1-500天编号为1到500, N个任务编号为500+1 到500+N, 汇点t(编号501+N).
源点s到每个任务i有边(s, i, Pi)
每一天到汇点有边(j, t, M) (其实这里的每一天不一定真要从1到500,只需要取那些被每个任务覆盖的每一天即可)
如果任务i能在第j天进行,那么有边(i, j, 1) 注意由于一个任务在一天最多只有1台机器执行,所以该边容量为1,不能为INF或M哦.
最后看最大流是否 == 所有任务所需要的总天数.

  1 #include <bits/stdc++.h>
  2
  3 using namespace std;
  4 const int maxn = 2000;
  5 const int inf = 0x3f3f3f3f;
  6 struct Edge
  7 {
  8     int from,to,cap,flow;
  9     Edge (int f,int t,int c,int fl)
 10     {
 11         from=f,to=t,cap=c,flow=fl;
 12     }
 13 };
 14 struct Dinic
 15 {
 16     int n,m,s,t;
 17     vector <Edge> edge;
 18     vector <int> G[maxn];//存图
 19     bool vis[maxn];//标记每点是否vis过
 20     int cur[maxn];//当前弧优化
 21     int dep[maxn];//标记深度
 22     void init(int n,int s,int t)//初始化
 23     {
 24         this->n=n;this->s=s;this->t=t;
 25         edge.clear();
 26         for (int i=0;i<n;++i) G[i].clear();
 27     }
 28     void addedge (int from,int to,int cap)//加边,单向边
 29     {
 30         edge.push_back(Edge(from,to,cap,0));
 31         edge.push_back(Edge(to,from,0,0));
 32         m=edge.size();
 33         G[from].push_back(m-2);
 34         G[to].push_back(m-1);
 35     }
 36     bool bfs ()
 37     {
 38         queue<int> q;
 39         while (!q.empty()) q.pop();
 40         memset(vis,false,sizeof vis);
 41         vis[s]=true;
 42         dep[s]=0;
 43         q.push(s);
 44         while (!q.empty()){
 45             int u=q.front();
 46             //printf("%d\n",u);
 47             q.pop();
 48             for (int i=0;i<G[u].size();++i){
 49                 Edge e=edge[G[u][i]];
 50                 int v=e.to;
 51                 if (!vis[v]&&e.cap>e.flow){
 52                     vis[v]=true;
 53                     dep[v]=dep[u]+1;
 54                     q.push(v);
 55                 }
 56             }
 57         }
 58         return vis[t];
 59     }
 60     int dfs (int x,int mi)
 61     {
 62         if (x==t||mi==0) return mi;
 63         int flow=0,f;
 64         for (int &i=cur[x];i<G[x].size();++i){
 65             Edge &e=edge[G[x][i]];
 66             int y=e.to;
 67             if (dep[y]==dep[x]+1&&(f=dfs(y,min(mi,e.cap-e.flow)))>0){
 68                 e.flow+=f;
 69                 edge[G[x][i]^1].flow-=f;
 70                 flow+=f;
 71                 mi-=f;
 72                 if (mi==0) break;
 73             }
 74         }
 75         return flow;
 76     }
 77     int max_flow ()
 78     {
 79         int ans = 0;
 80         while (bfs()){
 81             memset(cur,0,sizeof cur);
 82             ans+=dfs(s,inf);
 83         }
 84         return ans;
 85     }
 86 }dinic;
 87 int full_flow;
 88 int main()
 89 {
 90     int casee = 0;
 91     //freopen("de.txt","r",stdin);
 92     int T;scanf("%d",&T);
 93     while (T--){
 94         int n,m;
 95         full_flow = 0;
 96         scanf("%d%d",&n,&m);
 97         int src = 0,dst = 500+1+n;
 98         dinic.init(500+2+n,src,dst);
 99         bool vis[maxn];
100         memset(vis,false,sizeof vis);
101         for (int i=1;i<=n;++i){
102             int p,s,e;
103             scanf("%d%d%d",&p,&s,&e);
104             full_flow+=p;
105             dinic.addedge(src,i+500,p);
106             for (int j=s;j<=e;++j){
107                 vis[j]=true;
108                 dinic.addedge(i+500,j,1);
109             }
110         }
111         for (int i=0;i<maxn;++i){
112             if (vis[i])
113                 dinic.addedge(i,dst,m);
114         }
115         printf("Case %d: ",++casee);
116         if (dinic.max_flow()==full_flow){//dinic.max_flow()只能跑一遍
117             printf("Yes\n\n");
118         }
119         else
120             printf("No\n\n");
121     }
122     return 0;
123 }
时间: 2024-10-27 00:08:48

hdu 3572 Task Schedule (Dinic模板)的相关文章

hdu 3572 Task Schedule(网络流 dinic算法)

Task Schedule Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 3412    Accepted Submission(s): 1197 Problem Description Our geometry princess XMM has stoped her study in computational geometry t

HDU 3572 Task Schedule(ISAP)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3572 题意:m台机器,需要做n个任务.第i个任务,你需要使用机器Pi天,且这个任务要在[Si  ,  Ei]区间内完成才有效.对于一个任务,只能由一个机器来完成,一个机器同一时间只能做一个任务.当然,一个任务可以分成几段不连续的时间来完成.问,能否做完全部任务. 题意很清晰,也就是判断是否是满流. 对于网络流问题,模板大家都有,关键在于如何建图(详见资料) 思路:今天问了龙哥,对建图有了一定的了解,

hdu 3572 Task Schedule(最大流)

hdu 3572 Task Schedule 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 tas

HDU 3572 Task Schedule(拆点+最大流dinic)

Task Schedule Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 7753    Accepted Submission(s): 2381 Problem Description Our geometry princess XMM has stoped her study in computational geometry t

hdu 3572 Task Schedule 最大流 Dinic算法,,卡时间。。建图非常有讲究

Task Schedule Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 4617    Accepted Submission(s): 1513 Problem Description Our geometry princess XMM has stoped her study in computational geometry t

HDU 3572 Task Schedule (最大流)

C - Task Schedule Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Status Practice HDU 3572 Description Our geometry princess XMM has stoped her study in computational geometry to concentrate on her newly opened fac

hdu 3572 Task Schedule

Task Schedule 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

HDU 3572 Task Schedule(ISAP模板&amp;amp;&amp;amp;最大流问题)

题目链接:http://acm.hdu.edu.cn/showproblem.php? pid=3572 题意:m台机器.须要做n个任务. 第i个任务.你须要使用机器Pi天,且这个任务要在[Si  ,  Ei]区间内完毕才有效. 对于一个任务,仅仅能由一个机器来完毕.一个机器同一时间仅仅能做一个任务. 当然,一个任务能够分成几段不连续的时间来完毕.问,是否能做完所有任务. 题意非常清晰.也就是推断是否是满流. 对于网络流问题,模板大家都有,关键在于怎样建图(详见资料) 思路:今天问了龙哥,对建图

HDU 3572 Task Schedule(最大流Dinic算法)

该题非常经典,建图的方法非常巧妙,因为每个任务的完成不一定要连续,而且可以换机器完成,而且我们注意到时间点最多500,很小,所以我们将时间点抽出来建图. 对于每个任务,将其时间范围内的点与之连起来,容量显然为1 ,并与汇点相连,容量为p[i] .  对于每个时间点,因为最多可以有m台机器同时工作,所以容量为m . 一开始老想着任务和机器之间怎么建立联系了. 推荐题目: 点击打开链接 细节参见代码: #include<bits/stdc++.h> using namespace std; typ