# [SMOJ1870]旅行

//1870.cpp
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>

using namespace std;

const int MAXN = 50 + 10;
const int MAXM = 2450 + 50;
const int MAXT = 50 + 10;
const int INF = 0x3f3f3f3f;

#define MAXK (MAXN + MAXT)

struct Edge {
Edge *next;
int cap;
int dest;
} edges[(MAXM + MAXN) * MAXK << 1], *current, *first_edge[MAXK * MAXN]; //注意数组开够

int N, M, T;
int X[MAXM], Y[MAXM], Z[MAXM];
bool vis[MAXK * MAXN];

int s, t;

Edge *counterpart(Edge *x) {
return edges + ((x - edges) ^ 1);
}

void insert(int u, int v, int c) {
current -> next = first_edge[u];
current -> cap = c;
current -> dest = v;
first_edge[u] = current ++;
}

int dfs(int u, int f) {
if (u == t) return f;
if (vis[u]) return 0; else vis[u] = true;
for (Edge *p = first_edge[u]; p; p = p -> next)
if (p -> cap)
if (int res = dfs(p -> dest, min(f, p -> cap))) {
p -> cap -= res;
counterpart(p) -> cap += res;
return res;
}
return 0;
}

bool check(int k) {
s = 0; t = (k + 1) * N + 1; //同一层的点放一起
current = edges; fill(first_edge, first_edge + t + 1, (Edge*)0);
insert(s, 1, T); insert(1, s, 0); insert(t - 1, t, T); insert(t, t - 1, 0);
for (int i = 0; i < k; i++) {
for (int j = 1; j <= N; j++) insert(i * N + j, (i + 1) * N + j, INF), insert((i + 1) * N + j, i * N + j, 0);
for (int j = 0; j < M; j++) insert(i * N + X[j], (i + 1) * N + Y[j], Z[j]), insert((i + 1) * N + Y[j], i * N + X[j], 0);
}
int flows = 0;
for (;;) {
memset(vis, false, sizeof vis);
if (int res = dfs(s, INF)) flows += res; else return flows == T;
}
}

int solve() {
int l = 0, r = N + T; //(l, r]
while (l + 1 < r) {
int mid = l + r >> 1;
if (check(mid)) r = mid; else l = mid;
}
return r;
}

int main(void) {
freopen("1870.in", "r", stdin);
freopen("1870.out", "w", stdout);
scanf("%d%d%d", &N, &M, &T);
for (int i = 0; i < M; i++) scanf("%d%d%d", &X[i], &Y[i], &Z[i]);
printf("%d\n", solve());
return 0;
}

• 广告
• 抄袭
• 版权
• 政治
• 色情
• 无意义
• 其他

120