【题解】Catering World Finals 2015 上下界费用流

Code

#include <cstring>
#include <algorithm>
#include <cstdio>
#include <queue>
#include <cassert>

using namespace std;
const int MAXN = 1000;
const int MAXM = 100000;
const int INF = 0x3f3f3f3f;
int _w;

int x;
_w = scanf( "%d", &x );
return x;
}

namespace MCMF {
struct Edge {
int u, v, c, f, w;
Edge() {}
Edge( int u, int v, int c, int f, int w ):
u(u), v(v), c(c), f(f), w(w) {}
};

int n, m, s, t;
Edge edge[MAXM];

void init( int _n ) {
n = _n, m = 0;
for( int i = 0; i < n; ++i )
}
void adde( int u, int v, int c, int w ) {
edge[m] = Edge(u, v, c, 0, w);
edge[m] = Edge(v, u, 0, 0, -w);
}

queue<int> q;
int dis[MAXN], inq[MAXN], res[MAXN], from[MAXN];

bool spfa() {
for( int i = 0; i < n; ++i )
dis[i] = INF, inq[i] = 0;
dis[s] = 0, inq[s] = 1, q.push(s), res[s] = INF;
while( !q.empty() ) {
int u = q.front(); q.pop();
inq[u] = 0;
for( int i = head[u]; ~i; i = nxt[i] ) {
const Edge &e = edge[i];
if( e.c > e.f && dis[u] + e.w < dis[e.v] ) {
dis[e.v] = dis[u] + e.w;
from[e.v] = i;
res[e.v] = min( res[u], e.c-e.f );
if( !inq[e.v] )
inq[e.v] = 1, q.push(e.v);
}
}
}
return dis[t] != INF;
}
void augment() {
int f = res[t], u = t;
while( u != s ) {
int i = from[u];
edge[i].f += f;
edge[i^1].f -= f;
u = edge[i].u;
}
}
int solve( int _s, int _t ) {
s = _s, t = _t;
int cost = 0;
while( spfa() ) {
cost += res[t] * dis[t];
augment();
}
return cost;
}
}

int n, k, g[MAXN][MAXN];
int s, t, ss, tt, nid;
int in[MAXN], out[MAXN];

void adde( int u, int v, int l, int r, int w ) {
}

void solve() {
s = nid++, t = nid++, ss = nid++, tt = nid++;
for( int i = 1; i <= n; ++i )
in[i] = nid++, out[i] = nid++;
MCMF::init(nid);
for( int i = 2; i <= n; ++i ) {
adde(in[i], out[i], 1, 1, 0); // 每个点只能经过一次
}
for( int i = 1; i <= n; ++i )
for( int j = i+1; j <= n; ++j )
}