该算法的基本思想是连续增广路。
费用流入门题:戳这里戳这里
代码如下:
#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; }