HDU - 2883 kebab (最大流)
来源:互联网 发布:卓智网络是国企 编辑:程序博客网 时间:2024/05/17 00:51
题目大意:有一个烤肉老板,每个单位时间可以完成M的烤肉
现在有N位客人,给出每位客人来的时间,走的时间,烤肉的数量和每串烤肉所需的单位时间
问这个老板能否完成每位客人的需求
解题思路:这题和HDU 3572相似,但又不能像那题那样做,因为这题时间长度有点大
所以将时间区间当成一个点,将该区间连向超级汇点,容量为区间长度*M
将所有客人连向超级源点,容量为烤肉数量*每串烤肉所需时间
接下来的难点就是怎么将客人和时间区间连起来了
如果时间区间在客人来的时间和走的时间这段区间内,就表明这段时间可以用来帮客人烤肉,所以可以连接,容量为INF
这样图就建好了
附上大神的详细题解
详细题解
#include <cstdio>#include <cstring>#include <algorithm>#include <vector>#include <queue>using namespace std;#define N 1010#define INF 0x3f3f3f3fstruct 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[N], num[N], cur[N], d[N]; int t, s, n, m; bool vis[N]; vector<int> G[N]; 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 S[N], E[N], num[N], T[N], All[N];int n, m;void solve() { int t, cnt = 0, s = 0, Sum = 0; for (int i = 1; i <= n; i++) { scanf("%d%d%d%d", &S[i], &num[i], &E[i], &T[i]); All[cnt++] = S[i]; All[cnt++] = E[i]; Sum += num[i] * T[i]; } sort(All, All + cnt); cnt = unique(All, All + cnt) - All; t = n + cnt + 1; isap.init(t); for (int i = 1; i <= n; i++) isap.AddEdge(s, i, num[i] * T[i]); for (int i = 1; i < cnt; i++) { isap.AddEdge(i + n, t, (All[i] - All[i - 1]) * m); for (int j = 1; j <= n; j++) { if (S[j] <= All[i - 1] && E[j] >= All[i]) { isap.AddEdge(j, i + n, INF); } } } if (Sum == isap.Maxflow(s, t)) printf("Yes\n"); else printf("No\n");}int main() { while (scanf("%d%d", &n, &m) != EOF) { solve(); } return 0;}
0 0
- HDU 2883 kebab(最大流)
- HDU - 2883 kebab (最大流)
- HDU 2883 kebab 最大流(纯靠建图)
- hdu 2883 kebab(最大流)
- HDU 2883kebab(网络流之最大流)
- 【HDU】 2883 kebab(最大流+时间段离散化)
- hdu 2883 kebab(最大流dinic邻接表)
- HDU 2883 kebab(离散化+最大流)
- hdu 2883 kebab 【网络最大流】
- HDU 2883 kebab(最大流,满流)
- HDU 2883 kebab(离散化+最大流)
- HDU 2883 kebab(离散化+最大流)
- HDU 2883 kebab 最大流建模
- hdu 2883 kebab (最大流 + 建图)
- HDU -- 2883 kebab(最大流判满流)
- HDU 2883 kebab 最大流判满流
- hdu 3572 Task Schedule hdu 2883 kebab 最大流
- HDU 2883 kebab【最大流】(判断是否满流)
- 计算机英语学习(二)
- Google C++ Coding Style:右值引用(Rvalue Reference)
- JDOM解析XML
- Lubuntu 12.04开机启动应用程序脚本
- Leetcode 162 Find Peak Element 查找峰值元素(极大值)
- HDU - 2883 kebab (最大流)
- 封装类中实现另外两个Activity之间的跳转
- c++线程池
- c++编译链接
- CSDN的Markdown编辑器如何添加空格
- android Graphics(一):概述及基本几何图形绘制
- Android知识体系结构
- c++编译链接过程
- div里嵌套iframe,让iframe及div高度一起随内容自适应高度问题