HDU 2485
私はまだ最小割の内包を理解していないようです...この問題は少なくともいくつかの頂点を除いて、図のソース点と集約点が連通しないようにすることを求めている.最小分割の定義を考えてみると、図中の各エッジの流量が1であれば、最小分割は最小のエッジを除去し、図のソース点と集約点が連通しないようにする.この問題の各頂点を2つの頂点に分割し、真ん中を1つの流量のエッジで接続します...これにより,モデルは最小割モデルを満たす.もう1つの制限は、経路長がkより大きい経路は考慮しなくてもよい.ここでは、最小費用フローで図を作成するだけで、各エッジの費用は1であり、パス費用がkより大きい場合に最大フロープロセスを終了すればよい.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <memory.h>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <algorithm>
#include <iostream>
#include <sstream>
#define ll __int64
using namespace std;
typedef int typef;
typedef int typec;
#define inff 0x0fffffff
#define infc 0x0fffffff
#define N 100
#define E 10000
struct network
{
int nv, ne, pnt[E], nxt[E];
int vis[N], que[N], head[N], pv[N], pe[N];
typef flow, cap[E]; typec cost, dis[E], d[N];
void addedge(int u, int v, typef c, typec w) {
pnt[ne] = v; cap[ne] = c;
dis[ne] = w; nxt[ne] = head[u]; head[u] = ne++;
pnt[ne] = u; cap[ne] = 0;
dis[ne] = -w; nxt[ne] = head[v]; head[v] = ne++;
}
int mincost(int src, int sink, int limit) {
int i, k, f, r; typef mxf;
for(flow = 0, cost = 0; ; ) {
memset(pv, -1, sizeof(pv));
memset(vis, 0, sizeof(vis));
for(i = 0; i < nv; ++i) d[i] = infc;
d[src] = 0; pv[src] = src; vis[src] = 1;
for(f = 0, r = 1, que[0] = src; r != f; ) {
i = que[f++]; vis[i] = 0;
if(N == f) f = 0;
for(k = head[i]; k != -1; k = nxt[k])
if(cap[k] && dis[k]+d[i] < d[pnt[k]]) {
d[pnt[k]] = dis[k] + d[i];
if(0 == vis[pnt[k]]) {
vis[pnt[k]] = 1;
que[r++] = pnt[k];
if(N == r) r = 0;
}
pv[pnt[k]] = i; pe[pnt[k]] = k;
}
}
if(-1 == pv[sink]) break;
if (d[sink] > limit) break;
for(k = sink, mxf = inff; k != src; k = pv[k])
if(cap[pe[k]] < mxf) mxf = cap[pe[k]];
flow += mxf; cost += d[sink] * mxf;
for(k = sink; k != src; k = pv[k]) {
cap[pe[k]] -= mxf; cap[pe[k]^1] += mxf;
}
}
return cost;
}
void init(int v) {
nv = v; ne = 0;
memset(head, -1, 4 * v);
}
} D;
int main() {
int n, m, k, x, y;
while (scanf("%d %d %d", &n, &m, &k), n || m || k) {
D.init(n * 2);
for (int i = 0; i < n; i++)
D.addedge(i * 2, i * 2 + 1, 1, 0);
for (int i = 0; i < m; i++) {
scanf("%d %d", &x, &y);
x--, y--;
D.addedge(x * 2 + 1, y * 2, 1, 1);
}
D.mincost(1, (n - 1) * 2, k);
printf("%d
", D.flow);
}
return 0;
}