题目描述
大战将至, 美国决定实行计划经济。美国西部总共有 N 个城市,编号
为 0 ∼ N − 1,以及 M 条道路,道路是单向的。其中城市 0 是一个大城
市,里面住着 K 个人,而城市 N − 1 是一个农业城市。现在所有城市 0 的
居民都需要到城市 N − 1 去领取食物。由于担心体力不支,所以居民都会
采取开车的形式出行。但道路不是无限宽的,对于一条道路,会有 ci 的限
制,表示在同一天内,最多只能有 ci 辆车同时在这条道路上行驶。一条道
路的长度为 1,每辆车的行驶速度也可以假定为 1 每天。城市 N − 1 会在
每个居民都到达后马上开始发放食物。现在 Reddington 想知道,假如在最
优安排下,居民最早能在多少天后领到食物。假如没有居民那就不需要发
放食物,默认为第 0 天。
分析
没注意到多组输入卡了半天。。
首先我们去考虑这个过程,我们首先肯定去找一条能走的人最多的一条路,假设人流量为
x
x
x,时间为
t
t
t,我们去二分答案
m
i
d
mid
mid,那么我们有
t
t
t天是花在路上的,剩下的每一天都有
x
x
x人可以到达汇点,写一个费用流二分答案即可
代码
#pragma GCC optimize(3)
#include <bits/stdc++.h>
#define debug(x) cout<<#x<<":"<<x<<endl;
#define dl(x) printf("%lld\n",x);
#define di(x) printf("%d\n",x);
#define _CRT_SECURE_NO_WARNINGS
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(),(x).end()
#define fi first
#define se second
#define SZ(x) ((int)(x).size())
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> PII;
typedef vector<int> VI;
const ll INF = 0x3f3f3f3f3f3f3f3f;
const int N = 1020,M = N * N * 2;
const ll mod = 1000000007;
const double eps = 1e-9;
const double PI = acos(-1);
template<typename T>inline void read(T &a) {
char c = getchar(); T x = 0, f = 1; while (!isdigit(c)) {if (c == '-')f = -1; c = getchar();}
while (isdigit(c)) {x = (x << 1) + (x << 3) + c - '0'; c = getchar();} a = f * x;
}
int gcd(int a, int b) {return (b > 0) ? gcd(b, a % b) : a;}
int h[N],ne[M],e[M],idx;
int n,m,S,T;
ll w[M],f[M],incf[N],d[N],k;
int q[N],pre[N];
bool st[N];
int x[M],y[M];
ll z[M];
void add(int a,int b,ll c,ll d){
ne[idx] = h[a],e[idx] = b,f[idx] = c,w[idx] = d,h[a] = idx++;
ne[idx] = h[b],e[idx] = a,f[idx] = 0,w[idx] = -d,h[b] = idx++;
}
bool spfa(){
int hh = 0,tt = 1;
memset(d,0x3f,sizeof d);
memset(st,0,sizeof st);
memset(incf,0,sizeof incf);
q[0] = S,d[S] = 0,incf[S] = INF;
while(hh != tt){
int t = q[hh++];
if(hh == N) hh = 0;
st[t] = false;
for(int i = h[t];~i;i = ne[i]){
int ver = e[i];
if(f[i] && d[ver] > d[t] + w[i]){
pre[ver] = i;
d[ver] = d[t] + w[i];
incf[ver] = min(f[i],incf[t]);
if(!st[ver]){
q[tt++] = ver;
if(tt == N) tt = 0;
st[ver] = true;
}
}
}
}
return incf[T] > 0;
}
bool check(ll mid){
ll now = k;
for(int i = 0;i <= n;i++) h[i] = -1;
idx = 0;
for(int i = 1;i <= m;i++) add(x[i],y[i],z[i],1);
while(spfa()){
ll t = incf[T];
if(mid - d[T] + 1 < 0) return false;
now -= (mid - d[T] + 1) * incf[T];
if(now <= 0) return true;
for(int i = T;i != S;i = e[pre[i] ^ 1]){
f[pre[i]] -= t;
f[pre[i] ^ 1] += t;
}
}
return false;
}
int main() {
while(~scanf("%d%d%lld",&n,&m,&k)){
S = 0,T = n - 1;
for(int i = 1;i <= m;i++) read(x[i]),read(y[i]),read(z[i]);
if(!k){
puts("0");
continue;
}
ll l = 1,r = n + k + 1;
ll ans = 0;
while(l < r){
ll mid = (l + r) >> 1;
if(check(mid)) r = mid,ans = mid;
else l = mid + 1;
}
if(!ans) puts("No solution");
else dl(ans);
}
return 0;
}
/**
* ┏┓ ┏┓+ +
* ┏┛┻━━━┛┻┓ + +
* ┃ ┃
* ┃ ━ ┃ ++ + + +
* ████━████+
* ◥██◤ ◥██◤ +
* ┃ ┻ ┃
* ┃ ┃ + +
* ┗━┓ ┏━┛
* ┃ ┃ + + + +Code is far away from
* ┃ ┃ + bug with the animal protecting
* ┃ ┗━━━┓ 神兽保佑,代码无bug
* ┃ ┣┓
* ┃ ┏┛
* ┗┓┓┏━┳┓┏┛ + + + +
* ┃┫┫ ┃┫┫
* ┗┻┛ ┗┻┛+ + + +
*/