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.
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.
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.
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模板)的主要内容,如果未能解决你的问题,请参考以下文章
hdu 3572 Task Schedule (Dinic模板)