题目链接:
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算法
原文:https://www.cnblogs.com/fzl194/p/8910142.html