Codeforces Gym101170J:Jupiter Orbiter(最大流)
题意
有n次事件,q个队列,s个传感器。每个传感器接到一个队列,每个队列有一个容量。
接下来执行n次事件,每次事件都会有一个最大发送数据量d。和s个数据a,代表这次给每个s填入a的数据量。
每次事件执行完后都要将队列里面的数据发送总和为d的数据量。这一次事件的数据发送后队列剩余的数据可以给下一次事件用。问是否会有数据泄露(即给s填入的数据量能不能都发送出去)。
思路
最大流。
建图如下:
S->第i个事件的队列q1->第i个事件的队列q2->事件->T
第i个事件的队列q2->第i+1个事件的队列q1
容量:
S->第i个事件的所有队列q1 的容量为b,即输入给队列的数据量。
第i个事件的队列q1->第i个事件的队列q2->事件 和
第i个事件的队列q2->第i+1个事件的队列q1 的容量为c,即每个队列的最大容量。
事件->T 的容量为d,即每次可以放出去的数据量。
判断是否合法:∑b <= 最大流量。

#include <bits/stdc++.h>
using namespace std;
const int N = 2150;
const int INF = 0x3f3f3f3f;
typedef long long LL;
struct Edge {
int u, v, nxt, cap;
} edge[N*N*2];
int head[N], tot, cur[N], gap[N], dis[N], pre[N], qq[N], cc[N];
void Add(int u, int v, int cap) {
edge[tot] = (Edge) { u, v, head[u], cap }; head[u] = tot++;
edge[tot] = (Edge) { v, u, head[v], 0 }; head[v] = tot++;
}
int BFS(int S, int T) {
queue<int> que; que.push(T);
memset(dis, INF, sizeof(dis));
memset(gap, 0, sizeof(gap));
gap[0]++; dis[T] = 0;
while(!que.empty()) {
int u = que.front(); que.pop();
for(int i = head[u]; ~i; i = edge[i].nxt) {
int v = edge[i].v;
if(dis[v] == INF) {
dis[v] = dis[u] + 1;
gap[dis[v]]++;
que.push(v);
}
}
}
}
int ISAP(int S, int T, int n) {
BFS(S, T);
memcpy(cur, head, sizeof(cur));
int u = pre[S] = S, i, index, flow, ans = 0;
while(dis[S] < n) {
if(u == T) {
flow = INF, index = S;
for(i = S; i != T; i = edge[cur[i]].v)
if(flow > edge[cur[i]].cap) flow = edge[cur[i]].cap, index = i;
for(i = S; i != T; i = edge[cur[i]].v)
edge[cur[i]].cap -= flow, edge[cur[i]^1].cap += flow;
ans += flow, u = index;
}
for(i = cur[u]; ~i; i = edge[i].nxt)
if(edge[i].cap > 0 && dis[edge[i].v] == dis[u] - 1) break;
if(~i) {
pre[edge[i].v] = u; cur[u] = i; u = edge[i].v;
} else {
if(--gap[dis[u]] == 0) break;
int md = n;
for(i = head[u]; ~i; i = edge[i].nxt)
if(md > dis[edge[i].v] && edge[i].cap > 0) md = dis[edge[i].v], cur[u] = i;
gap[dis[u] = md + 1]++;
u = pre[u];
}
}
return ans;
}
int main() {
int n, q, s; scanf("%d%d%d", &n, &q, &s);
memset(head, -1, sizeof(head)); tot = 0;
int S = 0, T = n * q * 2 + n + 1;
for(int i = 1; i <= s; i++) scanf("%d", &qq[i]);
for(int i = 1; i <= q; i++) scanf("%d", &cc[i]);
int sum = 0;
for(int i = 1; i <= n; i++) {
int d; scanf("%d", &d);
Add(n * q * 2 + i, T, d); // 事件与汇点
for(int j = 1; j <= s; j++) {
int a; scanf("%d", &a); sum += a;
Add(S, qq[j] + (i - 1) * q, a); // 源点与第一个队
}
for(int j = 1; j <= q; j++) {
Add((i - 1) * q + j, (i - 1) * q + j + n * q, cc[j]); // 第一个队和第二个队
Add((i - 1) * q + j + n * q, n * q * 2 + i, cc[j]); // 第二个队和事件
if(i < n) Add((i - 1) * q + j + n * q, i * q + j, cc[j]); // 第二个队和下一个事件的第一个队
}
}
// int ans = ISAP(S, T, T + 1);
// printf("ans : %d\n", ans);
if(sum <= ISAP(S, T, T + 1)) puts("possible");
else puts("impossible");
return 0;
}
Codeforces Gym101170J:Jupiter Orbiter(最大流)的更多相关文章
- CodeForces 164C Machine Programming 费用流
Machine Programming 题目连接: http://codeforces.com/problemset/problem/164/B Descriptionww.co One remark ...
- Codeforces.1045A.Last chance(最大流ISAP 线段树优化建图)
题目链接 \(Description\) 你需要用给定的\(n\)个武器摧毁\(m\)架飞船中的某一些.每架飞船需要被摧毁恰好一次. 武器共三种:1.可以在给定的集合中摧毁一架飞船:2.可以摧毁区间\ ...
- codeforces gym 100357 I (费用流)
题目大意 给出一个或与表达式,每个正变量和反变量最多出现一次,询问是否存在一种方案使得每个或式中有且仅有一个变量的值为1. 解题分析 将每个变量拆成三个点x,y,z. y表示对应的正变量,z表示对应的 ...
- CodeForces 1187G Gang Up 费用流
题解: 先按时间轴将一个点拆成100个点. 第一个点相当于第一秒, 第二个点相当于第二秒. 在这些点之间连边, 每1流量的费用为c. 再将图上的边也拆开. 将 u_i 向 v_i+1 建边. 将 v_ ...
- Codeforces 708D 上下界费用流
给你一个网络流的图 图中可能会有流量不平衡和流量>容量的情况存在 每调整一单位的流量/容量 需要一个单位的花费 问最少需要多少花费使得原图调整为正确(可行)的网络流 设当前边信息为(u,v,f, ...
- java 节点流(字符流,字节流)和包装流(缓冲流,转换流)
结点流:直接对File类进行操作的文件流 package stream; import java.io.File; import java.io.FileNotFoundException; impo ...
- 2016-2017 ACM-ICPC Northwestern European Regional Programming Contest (NWERC 2016)
A. Arranging Hat $f[i][j]$表示保证前$i$个数字有序,修改了$j$次时第$i$个数字的最小值. 时间复杂度$O(n^3m)$. #include <bits/stdc+ ...
- Codeforces Gym 100002 E "Evacuation Plan" 费用流
"Evacuation Plan" Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/10 ...
- 【最大流】ECNA 2015 F Transportation Delegation (Codeforces GYM 100825)
题目链接: http://codeforces.com/gym/100825 题目大意: N(N<=600)个点,每个点有个名字Si,R(R<=200)个生产商在R个点上,F(F<= ...
随机推荐
- Matlab随笔之指派问题的整数规划
原文:Matlab随笔之指派问题的整数规划 注:除了指派问题外,一般的整数规划问题无法直接利用Matlab函数,必须Matlab编程实现分支定界法和割平面解法. 常用Lingo等专用软件求解整数规划问 ...
- 关于 Swift 中的 Array.contains 方法
Swift 2.0 中对语言进行了又一次的改进,这次将整个语言变得更加面向对象化,比如在 Swift 1.x 中如果要判断某个元素是否在数组中,就需要用到 contains 函数: if contai ...
- 2017 JavaScript 开发者的学习图谱
码云项目推荐 前端框架类 1.项目名称: 基于 Vue.js 的 UI 组件库 iView 项目简介:iView 是一套基于 Vue.js 的 UI 组件库,主要服务于 PC 界面的中后台产品. 特性 ...
- WM_SIZE后于WM_CREATE消息!!在窗口被创建时的顺序!
WM_SIZE procedure WMSize (var Message: TWMSize); message WM_SIZE; 参数说明 wParam: Specifies the type ...
- G1 安装 Linux Debian system
开发Android第五步,G1 安装 Linux Debian system 在 G1 上安装 Linux Debian system (Debian ARMEL) 要具备以下条件: (a) 最好是 ...
- Linux学习之“exit函数”
先看下"_exit"和"exit": exit被调用时,将冲刷所有的标准I/O流,关闭所有打开的文件描述符.在传统实现中,同时也将关闭标准I/O流.即表示标准输 ...
- 【Gerrit】自动设置reviewer
gerrit 提供了一种代码review解决方案,但每次代码提交之后都要设置每个commit的code reviewer, 实在是痛苦. gerrit 在官方说明文档里面提供了解决方法,地址:http ...
- C#调用Microsoft.DirectX.DirectSound.dll时出错
1.修改工程的编译选项.我的开发运行环境是Windows 10 x64系统.需要修改一下工程的编译选项,把AnyCPU改成x86的. 未能加载文件或程序集“Microsoft.DirectX.Dire ...
- 【转】跟面试官聊.NET垃圾收集,直刺面试官G点
装逼的面试官和装逼的程序员 我面试别人的时候,经常是按这种路子来面试: 看简历和面试题,从简历和面试题上找到一些技术点,然后跟应聘者聊. 聊某个技术点的时候,应聘者的回答会牵涉到其他的技术点,然后我会 ...
- java模拟post请求发送json数据
import com.alibaba.fastjson.JSONObject; import org.apache.http.client.methods.CloseableHttpResponse; ...