hdu 3572 Task Schedule (Dinic模板)

Posted 抓不住Jerry的Tom

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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 }

 

 

以上是关于hdu 3572 Task Schedule (Dinic模板)的主要内容,如果未能解决你的问题,请参考以下文章

HDU3572 Task Schedule 最大流

hdu 3572 Task Schedule (Dinic模板)

hdu 3572 Task Schedule

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

HDU - 3572-Task Schedule

HDU 3572 Task Schedule(最大流判断满流)