hdu2883 网络流 离散化 建图
来源:互联网 发布:ubuntu给予文件夹权限 编辑:程序博客网 时间:2024/05/21 19:47
题解转自大佬:http://blog.csdn.net/u013480600/article/details/38984057
题意:
给定n个顾客,第i号顾客在si到达,点了ni个羊肉串,每个羊肉串需要ti个时间烤好。顾客想要在ei得到,一个烤炉只烤m串。问你是否能满足所有顾客的要求?能的话输出“Yes”,否则输出“No”。
注意:这ni个羊肉串可以被分开来考,一个单独的羊肉串也能分开烤(比如一个单独的羊肉串需要ti时间,我们把它分成ti份同时烤的话,那么一个羊肉串可以在1个单位时间内拷完)
注意:每个顾客的任务必须在(si,ei]半开半闭的区间内完成.
分析:
本题与HDU3572有点类似:
http://blog.csdn.net/u013480600/article/details/38962999
其实本题的本质就是HDU3572的思想,每个顾客其实提出的是需要ni*ti个单位时间任务(甚至可以在1个时刻同时完成,因为一串羊肉串都可以在1个时刻烤完),但是你每个时间只能提供m个单位时间做任务. 但是这个题目的时间点覆盖1到100W,明显不能再把每个单独的时间看成一个点了,所以这题要把每个不重叠的子时间区间看成一个点.
首先读入所有任务的开始时间s[i]和结束时间e[i],然后对这些时间点排序,去重,得到cnt个时间点,然后我们就能得到cnt-1个半开半闭的子时间区间(前后两个子区间边界不重叠,且所有区间连起来正好覆盖了原来的整个大时间区间,该大时间区间也是半开,半闭的).
建图: 源点s编号0, n个任务编号1到n, cnt-1个区间编号n+1到n+cnt, 汇点t编号n+cnt+1.
源点到每个任务i有边(s,i,ni*ti)
每个时间区间j到汇点有边(j,t, 该区间覆盖的单位时间点数)
如果任务i包含时间区间j,那么有边(i,j,INF)
求最大流,看最大流 是否== 所有任务需要的单位时间之和即可.
代码:
#include <bits/stdc++.h>using namespace std;const int INF = 0x3f3f3f3f;const int maxn = 608;const int Mod = 1e9 + 7;#define ll long long#define mem(x,y) memset(x,y,sizeof(x))#define IO ios_base::sync_with_stdio(0), cin.tie(0);inline ll gcd(ll a, ll b) {return a % b == 0 ? b : gcd(b, a % b);}inline ll lcm(ll a, ll b) {return a / gcd(a, b) * b;}inline ll quick_pow(ll x, int k) {ll ans = 1; while (k) { if (k & 1) ans = (ans * x) % Mod; x = x * x % Mod; k >>= 1; } return ans;}int dep[maxn];struct Node { int v, w, re_id; Node() {}; Node(int a, int b, int c) { v = a, w = b, re_id = c; }};vector<Node> node[maxn];void addEdge(int u, int v, int w) { node[u].push_back(Node(v, w, node[v].size())); node[v].push_back(Node(u, 0, node[u].size() - 1));}int bfs(int s, int t) { queue<int> Q; mem(dep, -1); dep[s] = 0; Q.push(s); while (!Q.empty()) { int u = Q.front(); Q.pop(); for (int i = 0; i < node[u].size(); i++) { int v = node[u][i].v; if (node[u][i].w > 0 && dep[v] == -1) { dep[v] = dep[u] + 1; Q.push(v); } } } return dep[t] != -1;}int dfs(int s, int t, int f) { if (s == t || f == 0) return f; int sumf = 0; for (int i = 0; i < node[s].size(); i++) { int v = node[s][i].v; if (node[s][i].w > 0 && dep[v] == dep[s] + 1) { int tmp = dfs(v, t, min(f, node[s][i].w)); if (tmp > 0) { node[s][i].w -= tmp; node[v][node[s][i].re_id].w += tmp; sumf += tmp, f -= tmp; } } } if (sumf == 0) dep[s] = -1; return sumf;}int dinic(int s, int t) { int ans = 0; while (bfs(s, t)) ans += dfs(s, t, INF); return ans;}set<int> st;int main() { int N, M, s[202], need, e[202], t, ss = 0, tt = 602; while (scanf("%d%d", &N, &M) != EOF) { for (int i = 0; i < maxn; i++) node[i].clear(); st.clear(); int mx = 0, sum = 0; for (int i = 1; i <= N; i++) { scanf("%d%d%d%d", &s[i], &need, &e[i], &t); sum += need * t; addEdge(ss, i, need * t); st.insert(s[i]); st.insert(e[i]); } set<int>::iterator it = st.begin(), it2 = st.begin(); it2++; for (int i = 1; i < st.size(); i++, it++, it2++) { int b = *it2, a = *it; addEdge(i + N, tt, (b - a)*M); for (int j = 1; j <= N; j++) { if (s[j] <= a && e[j] >= b) addEdge(j, i + N, INF); } } if (dinic(ss, tt) == sum ) printf("Yes\n"); else printf("No\n"); }}
- hdu2883 网络流 离散化 建图
- HDU2883 kebab(中等) [最大流]判断满流(数据离散化)
- 【最大流】【HDU2883】【kebab】
- hdu2883(DINIC最大流)
- HDU2883 kebab(最大流)
- hdu2883
- hdu2883
- hdu 2883 网络流+离散化
- HDU2883.kebab
- hdu2883 kebab
- 【网络流】 HDU 2883 kebab 离散
- (intermediate) 网络流(时序模型+离散化) UVA 11167 - Monkeys in the Emei Mountain
- 离散动态贝叶斯网络
- hdu2883 kebab(判满流)
- 离散化
- 离散化
- 离散化
- 离散化
- 配置都对,jps查看datanode没有启动,为什么
- 2017 ACM-ICPC 亚洲区(南宁赛区)网络赛 F. Overlapping Rectangles(面积并)
- Java StringBuffer 和 StringBuilder 类
- 发布node项目到npm
- (spring-data-redis)SSM框架下使用redis作为mybatis的二级缓存
- hdu2883 网络流 离散化 建图
- ios-OC和Swift混编调用分类问题
- php单张图片上传插件免刷新,兼容手机,可实现类似微信图片上传的体验
- Java 数组
- Recurrent neural networks deep dive
- C++ MFC / VS2013 之四 对话框:(创建对话框模板和修改对话框属性)
- Linux Shell高级技巧(一)
- 附加数据库失败,操作系统错误 5:"5(拒绝访问。)"的解决办法
- Recording_linux c++下 try catch用法