该算法的基本思想是连续增广路。
费用流入门题:戳这里戳这里
代码如下:
#include <stdio.h>
#include <algorithm>
#include <string.h>
using namespace std;
#define Clear(A, X) memset (A, X, sizeof A)
//#define Copy(A, B) memcpy (A, B, sizeof A)
#define REP(I, A, B) for (int I = A; I < B: ++ I)
#define FF(I, A, B) for (int I = A; I <= B; ++ I)
#define Min(A, B) ((A) < (B) ? (A) : (B))
#define Max(A, B) ((A) > (B) ? (A) : (B))
const int maxN = 256;
const int maxE = 1000000;
const int maxQ = 1000000;
const int oo = 0x3f3f3f3f;
struct Edge {
//int from;
int to;
int cap;
//int rcap;
int cost;
int next;
} edge[maxE];
int adj[maxN], cntE;
int Q[maxQ], inq[maxN], head, tail;
int f[maxN];
int d[maxN];
int cur[maxN];
int sourse, sink;
int mcmf_cost, mcmf_flow;
void addedge (int from, int to, int cap, int cost) {
//edge[cntE].from = from;
edge[cntE].to = to;
edge[cntE].cap = cap;
//edge[cntE].rcap = cap;
edge[cntE].cost = cost;
edge[cntE].next = adj[from];
adj[from] = cntE ++;
//edge[cntE].from = to;
edge[cntE].to = from;
edge[cntE].cap = 0;
//edge[cntE].rcap = 0;
edge[cntE].cost = -cost;
edge[cntE].next = adj[to];
adj[to] = cntE ++;
}
int spfa () {
int u, v, cap, cost;
Clear (d, oo);
Clear (inq, 0);
d[sourse] = 0;
cur[sourse] = -1;
f[s] = oo ;
head = tail = 0;
Q[tail ++] = sourse;
while (head != tail) {
u = Q[head ++];
inq[u] = 0;
for (int i = adj[u]; i != -1; i = edge[i].next) {
v = edge[i].to, cap = edge[i].cap, cost = edge[i].cost;
if (cap > 0 && d[v] > d[u] + cost) {
d[v] = d[u] + cost;
f[v] = Min(f[u], cap);
cur[v] = i;
if (!inq[v]) {
Q[tail ++] = v;
inq[v] = 1;
}
}
}
}
if (d[sink] == oo) return 0;
mcmf_flow += f[t];
mcmf_cost += f[t] * d[sink];
for (int i = cur[sink]; i != -1; i = cur[edge[i ^ 1].to]) {
edge[i].cap -= f[t];
edge[i ^ 1].cap += f[t];
}
return 1;
}
int MCMF () {
mcmf_flow = mcmf_cost = 0;
while (spfa ()) ;
return mcmf_cost;
}
void init () {
Clear (adj, -1);
cntE = 0;
}
int n;
void work () {
init ();
sourse = 0; sink = n << 1 | 1;//sink = n * 2 + 1
FF (u, 1, n) {
addedge (sourse, u, 1, 0);
addedge (u + n, sink, 1, 0);
int v, cost;
while (~scanf ("%d", &v) && v) {
scanf ("%d", &cost);
addedge (u, v + n, 1, cost);
}
}
MCMF ();
printf (mcmf_flow == n ? "%d\n" : "N\n", mcmf_cost);
}
int main () {
while (~scanf ("%d", &n) && n) work();
return 0;
}