Gym - 101908G 二分答案+最大流

After the end of the truck drivers‘ strike, you and the rest of Nlog?nia logistics specialists now have the task of planning the refueling of the gas stations in the city. For this, we collected information on stocks of R refineries and about the demands of P

gas stations. In addition, there are contractual restrictions that some refineries cannot supply some gas stations; When a refinery can provide a station, the shorter route to transport fuel from one place to another is known.

The experts‘ task is to minimize the time all stations are supplied, satisfying their demands. The refineries have a sufficiently large amount of trucks, so that you can assume that each truck will need to make only one trip from a refinery to a gas station. The capacity of each truck is greater than the demand of any gas station, but it may be necessary to use more than one refinery.

Input

The first line of the input contains three integers P,R,C

, respectively the number of gas stations, the number of refineries and the number of pairs of refineries and gas stations whose time will be given (1≤P,R≤1000; 1≤C≤20000). The second line contains P integers Di (1≤Di≤104), representing the demands in liters of gasoline of the gas stations i=1,2,…,P, in that order. The third line contains R integers Ei (1≤Ei≤104), representing stocks, in liters of gasoline, of refineries i=1,2,…,R, in that order. Finally, the latest C lines describe course times, in minutes, between stations and refineries. Each of these rows contains three integers, I,J,T (1≤I≤P; 1≤J≤R; 1≤T≤106), where I is the ID of a post, J is the ID of a refinery and T is the time in the course of a refinery truck J to I. No pair (J,I)

repeats. Not all pairs are informed; If a pair is not informed, contractual restrictions prevents the refinery from supplying the station.

Output

Print an integer that indicates the minimum time in minutes for all stations to be completely filled up. If this is not possible, print ?1.

Examples

Input

3 2 520 10 1030 201 1 22 1 12 2 33 1 43 2 5

Output

4

Input

3 2 520 10 1025 301 1 32 1 12 2 43 1 23 2 5

Output

5

Input

4 3 910 10 10 2010 15 301 1 11 2 12 1 32 2 23 1 103 2 104 1 14 2 24 3 30

Output

-1

Input

1 2 24030 101 1 1001 2 200

Output

200

有点像费用流,但是复杂度过不去;

由于我们要求最短时间,考虑二分答案;

对于此时的时间,显然只有<=x的边才能相连,

并且该边的流量设为inf;

然后设立源点,汇点跑一下最大流,看是否满流即可;

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstdlib>
#include<cstring>
#include<string>
#include<cmath>
#include<map>
#include<set>
#include<vector>
#include<queue>
#include<bitset>
#include<ctime>
#include<deque>
#include<stack>
#include<functional>
#include<sstream>
//#include<cctype>
//#pragma GCC optimize(2)
using namespace std;
#define maxn 300005
#define inf 0x7fffffff
//#define INF 1e18
#define rdint(x) scanf("%d",&x)
#define rdllt(x) scanf("%lld",&x)
#define rdult(x) scanf("%lu",&x)
#define rdlf(x) scanf("%lf",&x)
#define rdstr(x) scanf("%s",x)
typedef long long  ll;
typedef unsigned long long ull;
typedef unsigned int U;
#define ms(x) memset((x),0,sizeof(x))
const long long int mod = 1e9;
#define Mod 1000000000
#define sq(x) (x)*(x)
#define eps 1e-5
typedef pair<int, int> pii;
#define pi acos(-1.0)
//const int N = 1005;
#define REP(i,n) for(int i=0;i<(n);i++)
typedef pair<int, int> pii;

inline int rd() {
	int x = 0;
	char c = getchar();
	bool f = false;
	while (!isdigit(c)) {
		if (c == ‘-‘) f = true;
		c = getchar();
	}
	while (isdigit(c)) {
		x = (x << 1) + (x << 3) + (c ^ 48);
		c = getchar();
	}
	return f ? -x : x;
}

ll gcd(ll a, ll b) {
	return b == 0 ? a : gcd(b, a%b);
}
int sqr(int x) { return x * x; }

/*ll ans;
ll exgcd(ll a, ll b, ll &x, ll &y) {
	if (!b) {
		x = 1; y = 0; return a;
	}
	ans = exgcd(b, a%b, x, y);
	ll t = x; x = y; y = t - a / b * y;
	return ans;
}
*/

int n, m;
int st, ed;
struct node {
	int u, v, nxt, w;
}edge[maxn << 1];

int head[maxn], cnt;

void addedge(int u, int v, int w) {
	edge[cnt].u = u; edge[cnt].v = v; edge[cnt].nxt = head[u];
	edge[cnt].w = w; head[u] = cnt++;
}

int rk[maxn];

int bfs() {
	queue<int>q;
	ms(rk);
	rk[st] = 1;
	q.push(st);
	while (!q.empty()) {
		int tmp = q.front(); q.pop();
		for (int i = head[tmp]; i != -1; i = edge[i].nxt) {
			int to = edge[i].v;
			if (rk[to] || edge[i].w <= 0)continue;
			rk[to] = rk[tmp] + 1; q.push(to);
		}
	}
	return rk[ed];
}

int dfs(int u, int flow) {
	if (u == ed)return flow;
	int add = 0;
	for (int i = head[u]; i != -1 && add < flow; i = edge[i].nxt) {
		int v = edge[i].v;
		if (rk[v] != rk[u] + 1 || !edge[i].w)continue;
		int tmpadd = dfs(v, min(edge[i].w, flow - add));
		if (!tmpadd) { rk[v] = -1; continue; }
		edge[i].w -= tmpadd; edge[i ^ 1].w += tmpadd;
		add += tmpadd;
	}
	return add;
}

int ans;
void dinic() {
	while (bfs())ans += dfs(st, inf);
}

int P, R, C;
int D[maxn], E[maxn], T;
int sum;
struct nd {
	int u, v, w;
}e[maxn];

bool chk(int x) {
	ms(edge); memset(head, -1, sizeof(head)); cnt = 0;
	ms(rk);
	ans = 0;
	st = 0; ed = P + R + 2;
	for (int i = 1; i <= R; i++)addedge(st, i, E[i]), addedge(i, st, 0);
	for (int i = 1; i <= P; i++)addedge(i + R, ed, D[i]), addedge(ed, i + R, 0);
	for (int i = 1; i <= C; i++) {
		if (x >= e[i].w) {
			addedge(e[i].v, e[i].u + R, inf); addedge(e[i].u + R, e[i].v, 0);
		}
	}
	dinic();
	if (ans == sum)return true;
	return false;
}
int main()
{
//	ios::sync_with_stdio(0);
	memset(head, -1, sizeof(head));

	P = rd(); R = rd(); C = rd();
	for (int i = 1; i <= P; i++) {
		D[i] = rd(); sum += D[i];// gas stations
	}
	for (int i = 1; i <= R; i++)E[i] = rd();
	for (int i = 1; i <= C; i++)e[i].u = rd(), e[i].v = rd(), e[i].w = rd();
	bool fg = 0;
	int l = 0, r = 1e7 + 1;
	int as = 0;
	while (l <= r) {
		int mid = (l + r) / 2;
		if (chk(mid)) {
			r = mid - 1; as = mid; fg = 1;
		}
		else l = mid + 1;
	}
	if (!fg)cout << -1 << endl;
	else cout << as << endl;
	return 0;
}

原文地址:https://www.cnblogs.com/zxyqzy/p/10353227.html

时间: 2024-11-11 18:27:34

Gym - 101908G 二分答案+最大流的相关文章

POJ 2112 Optimal Milking 二分答案+最大流

首先二分最长的边,然后删去所有比当前枚举的值长的边,算最大流,看是否能满足所有的牛都能找到挤奶的地方 #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <climits> #include <string> #include <iostream> #include <map> #include

BZOJ 1305 CQOI2009 dance跳舞 二分答案+最大流

题目大意:给定n个男生和n个女生,一些互相喜欢而一些不.举行几次舞会,每次舞会要配成n对.不能有同样的组合出现.每一个人仅仅能与不喜欢的人跳k次舞,求最多举行几次舞会 将一个人拆成两个点.点1向点2连一条流量为k的边.两个人若互相喜欢则点1之间连边,不喜欢则点2之间连边 对于每个要验证的x值 将每个人的点1向源或汇连一条流量为x的边 然后二分答案跑最大流就可以 #include<cstdio> #include<cstring> #include<iostream> #

BZOJ 1738: [Usaco2005 mar]Ombrophobic Bovines 发抖的牛( floyd + 二分答案 + 最大流 )

一道水题WA了这么多次真是.... 统考终于完 ( 挂 ) 了...可以好好写题了... 先floyd跑出各个点的最短路 , 然后二分答案 m , 再建图. 每个 farm 拆成一个 cow 点和一个 shelter 点, 然后对于每个 farm x : S -> cow( x ) = cow( x ) 数量 , shelter( x ) -> T = shelter( x ) 容量 ; 对于每个dist( u , v ) <= m 的 cow( u ) -> shelter( v

BZOJ 1189 HNOI 2007 紧急疏散 evacuate 二分答案 最大流

题目大意:紧急疏散.有一张地图,'.'表示人,'D'表示门,人需要走曼哈顿距离的单位时间才1能到达门.一个门一个时刻只能通过一个人.求多长时间能疏散完毕. 思路:二分答案+最大流满流判定.先BFS处理出每个人与门的距离.二分最小时间,然后连边.S向每个人连流量为1的边,每个人向二分的时间之内能到达的门连流量为1的边.每个门向T连流量为t的边.然后最大流判定是否满流. (数组大小我是瞎开的,写代码的时候要算好了在开!) CODE: #include <queue> #include <cs

HDU3081(KB11-N 二分答案+最大流)

Marriage Match II Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 4248    Accepted Submission(s): 1406 Problem Description Presumably, you all have known the question of stable marriage match. A

BZOJ 1189 HNOI2007 紧急疏散evacuate 二分答案+最大流

题目大意:给定一个m*n的地图,每个点有可能是空地.墙或者出口,每个空地初始站着一个人,每一时刻可以向周围走1格,门每一时刻只能通过一个人,求最短多少时间后所有人可以撤离 首先从每个出口出发开始广搜,得到每个空地到所有出口的距离 然后二分答案,每次建图如下: 从源点向每个空地一条流量为1的边 如果一个空地能在规定时间到达某个出口,就从这个空地出发向该出口链接一条流量为1的边 每个出口向汇点连接一条流量为时间的边 然后跑最大流验证即可 注意图有不连通的情况 所以广搜要清初值(这个没人会忘吧QAQ

luoguP1401 城市(二分答案+最大流)

题意 N(2<=n<=200)个城市,M(1<=m<=40000)条无向边,你要找T(1<=T<=200)条从城市1到城市N的路,使得最长的边的长度最小,边不能重复用. 题解 简单的网络流判定. 一看问法想到二分答案.然后边不能重复直接上网络流. (用边长小于mid的边建图然后跑最大流,最后比较流量和k) (然而不知为何写挂了) 1 #include<cstdio> 2 #include<cstring> 3 #include<queue&

BZOJ 3993 Sdoi2015 星际战争 二分答案+最大流

题目大意:有n个机器人和m个激光武器,每个武器有一个威力和能打的集合,同一时刻只能打一个机器人,问最少多久可以全灭 二分答案+网络流= = 注意二分上界 #include <cstdio> #include <cstring> #include <iomanip> #include <iostream> #include <algorithm> #define M 110 #define S 0 #define T (M-1) #define E

【BZOJ1189】【HNOI2007】紧急疏散evacuate 二分答案+最大流check

#include <stdio.h> int main() { puts("转载请注明出处"); puts("地址:blog.csdn.net/vmurder/article/details/43666807"); } 题解: 首先floyd或者bfs求出每个'.'到各个'D'的最短路 然后注意一个点不能经过一个门去另一个门,所以可以看到我的floyd略有一点点点点不同... 然后这个时间限制可以转化为对每个门的拆点,可以证明拆400个就够了. 然后分别