HDU - 3572 Task Schedule (最大流)
2015-08-04 00:04
435 查看
题目大意:有N个任务,M台机器。
每个任务有相应的起始时间,截至时间和完成时间
每台机器一小时可以做1个单位的工作量,每个任务的完成可以不连续,但每次只能由一台机器完成
问能否完成所有任务
解题思路:因为只有500分钟,所以可以将每分钟都设成1条边,连向超级汇点,容量为M
每个任务连接向超级源点,容量为完成时间
接着将任务连接像时间(分钟),连接的条件为,该时间在起始时间和截止时间这个区间之内
这样图就构成了
每个任务有相应的起始时间,截至时间和完成时间
每台机器一小时可以做1个单位的工作量,每个任务的完成可以不连续,但每次只能由一台机器完成
问能否完成所有任务
解题思路:因为只有500分钟,所以可以将每分钟都设成1条边,连向超级汇点,容量为M
每个任务连接向超级源点,容量为完成时间
接着将任务连接像时间(分钟),连接的条件为,该时间在起始时间和截止时间这个区间之内
这样图就构成了
[code]#include <cstdio> #include <cstring> #include <algorithm> #include <vector> #include <queue> using namespace std; #define N 1010 #define INF 0x3f3f3f3f struct Edge { int from, to, cap, flow; Edge() {} Edge(int from, int to, int cap, int flow): from(from), to(to), cap(cap), flow(flow) {} }; struct ISAP { int p , num , cur , d ; int t, s, n, m; bool vis ; vector<int> G ; vector<Edge> edges; void init(int n) { this->n = n; for (int i = 0; i <= n; i++) { G[i].clear(); d[i] = INF; } edges.clear(); } void AddEdge(int from, int to, int cap) { edges.push_back(Edge(from, to, cap, 0)); edges.push_back(Edge(to, from, 0, 0)); m = edges.size(); G[from].push_back(m - 2); G[to].push_back(m - 1); } bool BFS() { memset(vis, 0, sizeof(vis)); queue<int> Q; d[t] = 0; vis[t] = 1; Q.push(t); while (!Q.empty()) { int u = Q.front(); Q.pop(); for (int i = 0; i < G[u].size(); i++) { Edge &e = edges[G[u][i] ^ 1]; if (!vis[e.from] && e.cap > e.flow) { vis[e.from] = true; d[e.from] = d[u] + 1; Q.push(e.from); } } } return vis[s]; } int Augment() { int u = t, flow = INF; while (u != s) { Edge &e = edges[p[u]]; flow = min(flow, e.cap - e.flow); u = edges[p[u]].from; } u = t; while (u != s) { edges[p[u]].flow += flow; edges[p[u] ^ 1].flow -= flow; u = edges[p[u]].from; } return flow; } int Maxflow(int s, int t) { this->s = s; this->t = t; int flow = 0; BFS(); if (d[s] > n) return 0; memset(num, 0, sizeof(num)); memset(cur, 0, sizeof(cur)); for (int i = 0; i < n; i++) if (d[i] < INF) num[d[i]]++; int u = s; while (d[s] <= n) { if (u == t) { flow += Augment(); u = s; } bool ok = false; for (int i = cur[u]; i < G[u].size(); i++) { Edge &e = edges[G[u][i]]; if (e.cap > e.flow && d[u] == d[e.to] + 1) { ok = true; p[e.to] = G[u][i]; cur[u] = i; u = e.to; break; } } if (!ok) { int Min = n ; for (int i = 0; i < G[u].size(); i++) { Edge &e = edges[G[u][i]]; if (e.cap > e.flow) Min = min(Min, d[e.to]); } if (--num[d[u]] == 0) break; num[d[u] = Min + 1]++; cur[u] = 0; if (u != s) u = edges[p[u]].from; } } return flow; } }; ISAP isap; int n, m, cas = 1; int S , E , P ; void solve() { scanf("%d%d", &n, &m); int Max = -1, Sum = 0; for (int i = 1; i <= n; i++) { scanf("%d%d%d", &P[i], &S[i], &E[i]); Max = max(Max, E[i]); Sum += P[i]; } int s = 0, t = n + Max + 1; isap.init(t); for (int i = 1; i <= Max; i++) { isap.AddEdge(i + n, t, m); } for (int i = 1; i <= n; i++) { isap.AddEdge(s, i, P[i]); for (int j = S[i]; j <= E[i]; j++) { isap.AddEdge(i, j + n, 1); } } printf("Case %d: ", cas++); if (Sum == isap.Maxflow(s, t)) printf("Yes\n\n"); else printf("No\n\n"); } int main() { int test; scanf("%d", &test); while (test--) { solve(); } return 0; }
相关文章推荐
- PHP微信支付开发实例
- wkhtmltopdf:一个 Linux 中将网页转成 PDF 的智能工具
- 自定义Android的EditText实现仿淘宝登录功能
- uva 10969
- 如何使用 pdfgrep 从终端搜索 PDF 文件
- 在Linux下如何修改Mysql的用户(root)的密码
- 详解ASP.NET七大身份验证方式以及解决方案
- 浅谈python多线程和队列管理shell程序
- python利用装饰器进行运算的实例分析
- Python实现字典的key和values的交换
- 使用python加密自己的密码
- python利用datetime模块计算时间差
- 合并百度影音的离线数据( with python 2.3)
- Python利用ansible分发处理任务
- 解决Python传递中文参数的问题
- python删除列表内容
- python函数局部变量用法实例分析
- 将Python代码打包为jar软件的简单方法
- Python简明入门教程
- python函数形参用法实例分析