1. 程式人生 > >hdu-3572 Task Schedule---最大流判斷滿流+dinic算法

hdu-3572 Task Schedule---最大流判斷滿流+dinic算法

push_back size 分段 amp con AS mda tro iter

題目鏈接:

http://acm.hdu.edu.cn/showproblem.php?pid=3572

題目大意:

給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哦.

最後看最大流是否 == 所有任務所需要的總天數.

用增廣路最大流會超時,得用dinic算法優化找增廣路

(圖論的題目難在如何建圖,而不是算法的使用)

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 typedef long long ll;
4 const int maxn = 1000 + 10; 5 const int INF = 1e9; 6 struct edge 7 { 8 int u, v, c, f; 9 edge(){} 10 edge(int u, int v, int c, int f):u(u), v(v), c(c), f(f){} 11 }; 12 vector<edge>e; 13 vector<int>G[maxn]; 14 int level[maxn];//BFS分層 15 int iter[maxn];//當前弧優化 16 int
n, m; 17 void init() 18 { 19 for(int i = 0; i < maxn; i++)G[i].clear(); 20 e.clear(); 21 } 22 void addedge(int u, int v, int c) 23 { 24 e.push_back(edge(u, v, c, 0)); 25 e.push_back(edge(v, u, 0, 0)); 26 int m = e.size(); 27 G[u].push_back(m - 2); 28 G[v].push_back(m - 1); 29 } 30 void BFS(int s) 31 { 32 memset(level, -1, sizeof(level)); 33 queue<int>q; 34 level[s] = 0; 35 q.push(s); 36 while(!q.empty()) 37 { 38 int u = q.front(); 39 q.pop(); 40 for(int i = 0; i < G[u].size(); i++) 41 { 42 edge& now = e[G[u][i]]; 43 int v = now.v; 44 if(now.c > now.f && level[v] < 0) 45 { 46 level[v] = level[u] + 1; 47 q.push(v); 48 } 49 } 50 } 51 } 52 int dfs(int u, int t, int f)//u為當前點,t為終點,f為當前流量 53 { 54 if(u == t)return f; 55 for(int& i = iter[u]; i < G[u].size(); i++)//當前弧優化 56 { 57 edge& now = e[G[u][i]]; 58 int v = now.v; 59 if(now.c > now.f && level[u] < level[v]) 60 { 61 int d = dfs(v, t, min(f, now.c - now.f)); 62 if(d > 0) 63 { 64 now.f += d; 65 e[G[u][i] ^ 1].f -= d; 66 return d; 67 } 68 } 69 } 70 return 0; 71 } 72 int Maxflow(int s, int t) 73 { 74 int flow = 0; 75 for(;;) 76 { 77 BFS(s); 78 if(level[t] < 0)return flow; 79 memset(iter, 0, sizeof(iter)); 80 int f; 81 while((f = dfs(s, t, INF)) > 0)flow += f; 82 } 83 return flow; 84 } 85 int main() 86 { 87 int T, cases = 0; 88 scanf("%d", &T); 89 while(T--) 90 { 91 scanf("%d%d", &n, &m); 92 int maxday = 0; 93 int sumday = 0; 94 init(); 95 int p, s, e; 96 for(int i = 1; i <= n; i++) 97 { 98 scanf("%d%d%d", &p, &s, &e); 99 addedge(0, 500 + i, p); 100 for(int j = s; j <= e; j++) 101 addedge(i + 500, j, 1); 102 maxday = max(maxday, e); 103 sumday += p; 104 } 105 for(int i = 1; i <= maxday; i++) 106 addedge(i, 501 + n, m); 107 if(Maxflow(0, 501 + n) == sumday) 108 printf("Case %d: Yes\n\n", ++cases); 109 else printf("Case %d: No\n\n", ++cases); 110 } 111 return 0; 112 }

hdu-3572 Task Schedule---最大流判斷滿流+dinic算法