ZOJ 3229 Shoot the Bullet (有源有汇有上下界最大流)
题意:一个人要给女孩子们拍照,一共 n 天,m 个女孩子,每天他至多拍 d[i] 张照片,每个女孩子总共要被至少拍 g[i] 次。在第 i 天,可以拍 c[i] 个女孩子,c[i] 个女孩子中每个女孩子在当天被拍的次数是 [li,ri],求最多可以拍多少张照片,以及每天每个可以拍的女孩子被拍了多少张照片。
析:一个很明显网络流,很容易建图,建立一个源点 s 和汇点 t,然后 s 向每一天连一条边,容量上界上 d[i],每个女孩子向汇点连一边,下界是 g[i], 上界是无穷大,然后对于每一天拍的从每一天那个结点向那个女孩子连一条容量上界是 ri,下界是 li,的边,然后就建好图了,就是求最大流,但是这个不是普通的网络流,我们要把它进行转换,首先先根据无源无汇的,建立,因为是有源汇的,所以连一条边 t -> s,INF,然后求一次 超级源点汇点(注意不是 s t) S T 最大流,如果满流就是有可行流,然后再求 s->t 的最大流,结果就是答案。然后再输出解,输出解的时候就是流再加上下界。
代码如下:
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <cstdio>
#include <string>
#include <cstdlib>
#include <cmath>
#include <iostream>
#include <cstring>
#include <set>
#include <queue>
#include <algorithm>
#include <vector>
#include <map>
#include <cctype>
#include <cmath>
#include <stack>
#include <sstream>
#include <list>
#include <assert.h>
#include <bitset>
#include <numeric>
#define debug() puts("++++")
#define gcd(a, b) __gcd(a, b)
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define fi first
#define se second
#define pb push_back
#define sqr(x) ((x)*(x))
#define ms(a,b) memset(a, b, sizeof a)
#define sz size()
#define be begin()
#define ed end()
#define pu push_up
#define pd push_down
#define cl clear()
#define lowbit(x) -x&x
//#define all 1,n,1
#define FOR(i,n,x) for(int i = (x); i < (n); ++i)
#define freopenr freopen("in.in", "r", stdin)
#define freopenw freopen("out.out", "w", stdout)
using namespace std; typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int, int> P;
const int INF = 0x3f3f3f3f;
const LL LNF = 1e17;
const double inf = 1e20;
const double PI = acos(-1.0);
const double eps = 1e-8;
const int maxn = 1500 + 50;
const int maxm = 1e6 + 10;
const LL mod = 1000000007;
const int dr[] = {-1, 1, 0, 0, 1, 1, -1, -1};
const int dc[] = {0, 0, 1, -1, 1, -1, 1, -1};
const char *de[] = {"0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111", "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111"};
int n, m;
const int mon[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
const int monn[] = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
inline bool is_in(int r, int c) {
return r >= 0 && r < n && c >= 0 && c < m;
}
inline int readInt(){ int x; scanf("%d", &x); return x; } struct Edge{
int from, to, cap, flow;
}; struct Dinic{
int n, m, s, t;
vector<Edge> edges;
vector<int> G[maxn];
bool vis[maxn];
int d[maxn];
int cur[maxn]; void init(int n){
FOR(i, n, 0) G[i].cl;
edges.cl;
} void addEdge(int from, int to, int cap){
edges.pb((Edge){from, to, cap, 0});
edges.pb((Edge){to, from, 0, 0});
m = edges.sz;
G[from].pb(m - 2);
G[to].pb(m - 1);
} bool bfs(){
ms(vis, 0); d[s] = 0; vis[s] = 1;
queue<int> q; q.push(s); while(!q.empty()){
int u = q.front(); q.pop();
for(int i = 0; i < G[u].sz; ++i){
Edge &e = edges[G[u][i]];
if(!vis[e.to] && e.cap > e.flow){
vis[e.to] = 1;
d[e.to] = d[u] + 1;
q.push(e.to);
}
}
}
return vis[t];
} int dfs(int u, int a){
if(u == t || a == 0) return a;
int flow = 0, f;
for(int &i = cur[u]; i < G[u].sz; ++i){
Edge &e = edges[G[u][i]];
if(d[e.to] == d[u] + 1 && (f = dfs(e.to, min(a, e.cap-e.flow))) > 0){
e.flow += f;
edges[G[u][i]^1].flow -= f;
flow += f;
a -= f;
if(a == 0) break;
}
}
return flow;
} int maxFlow(int s, int t){
this->s = s; this->t = t;
int flow = 0;
while(bfs()){ ms(cur, 0); flow += dfs(s, INF); }
return flow;
}
};
Dinic dinic; int down[100000], in[100000], d[maxn], g[maxn]; int main(){
while(scanf("%d %d", &n, &m) == 2){
int s = 0, t = n + m + 1;
dinic.init(t + 10);
ms(in, 0);
for(int i = 1; i <= m; ++i)
scanf("%d", g + i); int cnt = 0;
for(int i = 1; i <= n; ++i){
int c; scanf("%d %d", &c, d + i);
int x, l, r;
while(c--){
scanf("%d %d %d", &x, &l, &r);
down[cnt++] = l;
dinic.addEdge(i, x + n + 1, r - l);
in[i] -= l;
in[x+n+1] += l;
}
}
for(int i = 1; i <= n; ++i)
dinic.addEdge(s, i, d[i]);
for(int i = 1; i <= m; ++i){
dinic.addEdge(i + n, t, INF - g[i]);
in[i+n] -= g[i];
in[t] += g[i];
}
int S = t + 1, T = t + 2;
int ans = 0;
for(int i = 0; i <= t; ++i)
if(in[i] > 0) dinic.addEdge(S, i, in[i]), ans += in[i];
else if(in[i] < 0) dinic.addEdge(i, T, -in[i]);
dinic.addEdge(t, s, INF);
if(ans != dinic.maxFlow(S, T)){ printf("-1\n\n"); continue; }
printf("%d\n", dinic.maxFlow(s, t));
for(int i = 0; i < cnt; ++i) printf("%d\n", dinic.edges[i<<1].flow + down[i]);
printf("\n");
}
return 0;
}
ZOJ 3229 Shoot the Bullet (有源有汇有上下界最大流)的更多相关文章
- SGU 176 Flow construction (有源有汇有上下界最小流)
题意:给定 n 个点,m 条有向边,如果有向边的标号是1的话,就表示该边的上界下界都为容量 ,如果有向边的标号为0的哈,表示该边的下界为0,上界为容量 ,现在问,从 1 到 n 的最小流是多少,并输出 ...
- ZOJ 2314 (sgu 194) Reactor Cooling (无源汇有上下界最大流)
题意: 给定n个点和m条边, 每条边有流量上下限[b,c], 求是否存在一种流动方法使得每条边流量在范围内, 而且每个点的流入 = 流出 分析: 无源汇有上下界最大流模板, 记录每个点流的 in 和 ...
- ZOJ 3229 Shoot the Bullet(有源汇上下界最大流)
题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=3442 题目大意: 一个屌丝给m个女神拍照,计划拍照n天,每一天屌丝给 ...
- ZOJ - 3229 Shoot the Bullet (有源汇点上下界最大流)
题意:要在n天里给m个女生拍照,每个女生有拍照数量的下限Gi,每天有拍照数量的上限Di,每天当中每个人有拍照的上限Lij和Rij.求在满足限制的基础上,所有人最大能拍多少张照片. 分析:抛开限制,显然 ...
- POJ 2396 有源有汇有上下界可行流问题
题意:给一个矩阵,给出每行每列之和,附加一些条件,如第i行第j列数必需大于(小于)多少. 思路题解:矩阵模型,模拟网络流,行.列标号为结点,构图,附加s,t,s连行标(容量上下限每行之和(必需以这个 ...
- ZOJ 3229 Shoot the Bullet | 有源汇可行流
题目: 射命丸文要给幻想乡的居民照相,共照n天m个人,每天射命丸文照相数不多于d个,且一个人n天一共被拍的照片不能少于g个,且每天可照的人有限制,且这些人今天照的相片必须在[l,r]以内,求是否有可行 ...
- ZOJ 3229 Shoot the Bullet(有源汇的上下界最大流)
Description Gensokyo is a world which exists quietly beside ours, separated by a mystical border. It ...
- ZOJ 3229 Shoot the Bullet [上下界最大流]
ZOJ 3229 Shoot the Bullet 题意:此生无悔入东方 上下界最大流 spj挂掉了我也不知道对不对,把代码放这里吧以后正常了可能会评测一下 #include <iostream ...
- Shoot the Bullet(有源汇带上下界最大流)
有源汇带上下界最大流 在原图基础上连一条汇点到源点流量为inf的边,将有源汇网络流转化为无源汇网络流用相同方法判断是否满流,如果满流再跑一边源点到汇点的最大流就是答案 例题:Shoot the Bul ...
随机推荐
- C语言 链表(VS2012版)
// ConsoleApplication2.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include <stdio.h> ...
- vim常用操作和使用技巧
vi是linux与unix下的常用文本编辑器,其运行稳定,使用方便,本文将分两部分对其常用操作技巧和配置进行阐述,其中参考了网上的一些文章,对作者表示感谢 PART1 操作技巧 说明: 以下的例子中 ...
- BeanUtils接口和类
Jakarta Commons项目提供了相当丰富的API,我们之前了解到的Commons Lang只是众多API的比较核心的一小部分而已.Commons下面还有相当数量的子项目,用于解决各种各样不 ...
- android 开发 View _9_ 实现渐变功能(直线与圆形)
参考博客:https://blog.csdn.net/iispring/article/details/50500106/ android颜色渐变的分类有: LinearGradient线性渐变 线性 ...
- Docekr 挂在卷之后访问目录时异常 cannot open directory '.': Permission denied 的解决办法
1,原因,原因是CentOS7 中的安全模块 selinux 把权限禁掉了 2,解决办法如下 2.1,运行容器是加参数在 --privileged=true (个人认为这是最佳方式,推荐使用) 如 ...
- JAVA 注解,泛型,反射获取泛型,并实例化
JAVA 的泛型加大了 编程的灵活性,在配合上反射,可以让我们省去大量的重复代码,当你用 SpringBoot 整合 JPA 的时候 你会发现,你的 DAO 层只需要继承 BaseDao,在显示标明泛 ...
- This iPhone 6s is running iOS 11.3.1 (15E302), which may not be supported by this version of Xcode.
This iPhone 6s is running iOS 11.3.1 (15E302), which may not be supported by this version of Xcode.
- poi横纵导出
dao <select id="selectTargetModel" resultMap="targetMap"> select si.SHOP_N ...
- python杂记一
1. 输出CSV文件 用python输出csv文件不难,可是MS office excel和WPS 对输出的CSV文件打开规则不一样. WPS可以支持CSV以'\t'为分隔符,打开文件直接写内容 MS ...
- k8s定义Deployment,和service
定义一个Deployment和service做个简单的笔记 有时候我们需要开放Pod的多个端口,比如nginx的80和443端口,那如何定义Deployment文件呢,定义单个端口如下 apiVers ...