求两条不相交从1到n路径的长度和的最小值.
每个点拆成入点出点,流量1费用为边权,拆成的两个点流量为1费用为0,除了源点和汇点流量为2.
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <vector> #include <queue> using namespace std; #define INF 11111111 #define maxn 2111 #define maxm 2111111 int n, m; int s, t; struct node { int u, v, next, cap, flow, cost; }edge[maxm]; int head[maxn], cnt; int pre[maxn], dis[maxn]; bool vis[maxn]; int N; void init () { memset (head, -1, sizeof head); cnt = 0; } void add_edge (int u, int v, int cap, int cost) { edge[cnt].u = u, edge[cnt].v = v, edge[cnt].cap = cap, edge[cnt].flow = 0; edge[cnt].cost = cost, edge[cnt].next = head[u], head[u] = cnt++; edge[cnt].u = v, edge[cnt].v = u, edge[cnt].cap = 0, edge[cnt].flow = 0; edge[cnt].cost = -cost, edge[cnt].next = head[v], head[v] = cnt++; } bool spfa (int s, int t) { queue <int> q; for (int i = 0; i < N; i++) { dis[i] = INF; vis[i] = 0; pre[i] = -1; } dis[s] = 0; vis[s] = 1; q.push (s); while (!q.empty ()) { int u = q.front (); q.pop (); vis[u] = 0; for (int i = head[u]; i != -1; i = edge[i].next) { int v = edge[i].v; if (edge[i].cap > edge[i].flow && dis[v] > dis[u]+edge[i].cost) { dis[v] = dis[u]+edge[i].cost; pre[v] = i; if (!vis[v]) { vis[v] = 1; q.push (v); } } } } if (pre[t] == -1) return 0; else return 1; } int MCMF (int s, int t, int &cost) { int flow = 0; cost = 0; while (spfa (s, t)) { int Min = INF; for (int i = pre[t]; i != -1; i = pre[edge[i^1].v]) { if (Min > edge[i].cap-edge[i].flow) { Min = edge[i].cap-edge[i].flow; } } for (int i = pre[t]; i != -1; i = pre[edge[i^1].v]) { edge[i].flow += Min; edge[i^1].flow -= Min; cost += edge[i].cost*Min; } flow += Min; } return flow; } int main () { //freopen ("in.txt", "r", stdin); while (scanf ("%d%d", &n, &m) == 2) { init (); add_edge (0, 1, 2, 0); add_edge (2*(n-1), 2*(n-1)+1, 2, 0); for (int i = 1; i < n-1; i++) { add_edge (i*2, i*2+1, 1, 0); } for (int i = 0; i < m; i++) { int u, v, w; scanf ("%d%d%d", &u, &v, &w); u--, v--; add_edge (2*u+1, 2*v, 1, w); } int cost = 0; N = 2*n; s = 0, t = 2*(n-1); MCMF (s, t, cost); printf ("%d\n", cost); } return 0; }