#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
#define mxn 402
#define inf 0x3f3f3f3f
#define mxe 50020
struct edge {
int u, v, cap, flow, nxt;
edge() {}
edge( int u, int v, int cap, int flow, int nxt ):
u( u ), v( v ), cap( cap ), flow( flow ), nxt( nxt ) {}
};
struct dinic {
int s, t, cc;
int cur[mxn], d[mxn];
int fst[mxn];
edge e[mxe];
void init() {
memset( fst, -1, sizeof( fst ) );
cc = 0;
}
void add( int u, int v, int cap ) {
e[cc] = edge( u, v, cap, 0, fst[u] );
fst[u] = cc++;
e[cc] = edge( v, u, 0, 0, fst[v] );
fst[v] = cc++;
}
bool bfs() {
memset( d, -1, sizeof( d ) );
queue<int> q;
d[s] = 0;
q.push( s );
while( !q.empty() ) {
int x = q.front(); q.pop();
for( int i = fst[x]; ~i; i = e[i].nxt ) {
int v = e[i].v;
if( d[v] == -1 && e[i].cap > e[i].flow ) {
d[v] = d[x] + 1;
q.push( v );
}
}
}
return ~d[t];
}
int dfs( int x, int a ) {
if( x == t || a == 0 )
return a;
int flow = 0, f;
for( int& i = cur[x]; ~i; i = e[i].nxt ) {
if( i == inf )
i = fst[x];
if( i == -1 )
break;
int v = e[i].v;
if( d[v] == d[x] + 1 && ( f = dfs( v, min( a, e[i].cap - e[i].flow ) ) ) > 0 ) {
a -= f;
e[i].flow += f;
e[i^1].flow -= f;
flow += f;
if( !a )
break;
}
}
return flow;
}
int go( int s, int t ) {
this -> s = s, this -> t = t;
int flow = 0;
while( bfs() ) {
memset( cur, 0x3f, sizeof( cur ) );
flow += dfs( s, inf );
}
return flow;
}
}go;
int n, C, m;
int d[mxn][mxn];
int S, T;
void read() {
for( int i = 1; i <= n + C; ++i ) {
for( int j = 1; j <= n + C; ++j ) {
scanf( "%d", &d[i][j] );
if( d[i][j] == 0 && i != j )
d[i][j] = inf;
}
}
for( int k = 1; k <= n + C; ++k )
for( int i = 1; i <= n + C; ++i )
for( int j = 1; j <= n + C; ++j )
d[i][j] = min( d[i][k] + d[k][j], d[i][j] );
}
int main() {
while( scanf( "%d%d%d", &n, &C, &m ) != EOF ) {
read();
S = 0, T = n + C + 1;
int head = 0, tail = inf;
while( head < tail ) {
go.init();
int mid = ( head + tail ) / 2;
for( int i = 1; i <= n; ++i ) {
for( int j = n + 1; j <= n + C; ++j )
if( d[i][j] <= mid )
go.add( i, j, 1 );
go.add( S, i, m );
}
for( int i = n + 1; i <= n + C; ++i )
go.add( i, T, 1 );
if( go.go( S, T ) == C )
tail = mid;
else
head = mid + 1;
}
printf( "%d\n", head );
}
return 0;
}
POJ 2112Optimal Milking 最大流

最新推荐文章于 2019-09-25 23:24:23 发布
