Topic Link: Click to open the link
Test instructions
A graph with a forward edge for a given n points m bar, beginning S, end point T
Below M edge U,v, a, b if you choose this side to spend a, do not choose to spend a
Constructing a Euler path makes the starting point S, the end point is T, and the cost is minimized.
Ideas:
First you can think of a simple idea: Assume that all sides are selected, and then run in the expense flow, there will be a negative ring problem.
So to avoid negative loops, make all the costs positive:
int sum = 0;
If a>b, then the cost is to be only a-B, the default side is to delete is, sum + +, then if we want to select this edge, then from the U=>v, the cost is a B, the flow is 1
If a<b, then the cost to be positive can only be b-a, the default side is the choice is, sum + = A, then if we want to delete this edge, it is equivalent to choose a reverse side, that is, v=>u, the cost is b-a, the traffic is 1
Because we want to keep the flow uniform, so we use fried chicken Huiyuan to maintain,
#include <cstdio> #include <cstring> #include <queue> #include <algorithm> #include < Iostream>template <class t>inline BOOL Rd (T &ret) {char c; int sgn;if (c = GetChar (), c = = EOF) return 0;whil E (c! = '-' && (c< ' 0 ' | | c> ' 9 ')) C = GetChar (); sgn = (c = = '-')? -1:1;ret = (c = = '-')? 0: (C-' 0 '); while (c = GetChar (), C >= ' 0 ' &&c <= ' 9 ') ret = ret * + (C-' 0 '); ret *= Sgn;return 1;} Template <class t>inline void pt (T x) {if (x <0) {Putchar ('-'); x = x;} if (x>9) pt (X/10);p Utchar (x% 10 + ' 0 ');} using namespace std;typedef int ll; #define INF 0x3f3f3f3f #define N 300#define M 605*605*4 struct Edge {ll to, cap, cost , NEX; Edge () {}edge (LL-to, LL-cap, LL-cost, LL-next): To, Cap (CAP), cost, NEX (next) {}} edge[m << 1];ll head[n], E Dgenum;ll D[n], a[n], P[n];bool inq[n];void Add (ll from, LL-to, LL-cap, ll cost) {Edge[edgenum] = edge (to, cap, cost, head [from]); Head[from] = Edgenum++;edge[edgenum] = EDge (from, 0,-cost, head[to]); head[to] = edgenum++;} BOOL SPFA (ll S, ll T, LL &flow, ll &cost) {for (ll i = 0; I <= t; i++) D[i] = Inf;memset (inq, 0, sizeof inq); Qu Eue<ll>q;q.push (s);D [s] = 0; A[s] = Inf;while (!q.empty ()) {ll u = Q.front (); Q.pop (); Inq[u] = 0;for (ll i = head[u]; ~i; i = Edge[i].nex) {Edge &e = Edge[i];if (e.cap && d[e.to] > D[u] + e.cost) {d[e.to] = D[u] + e.cost; P[e.to] = i; A[e.to] = min (A[u], e.cap), if (!inq[e.to]) {inq[e.to] = 1; Q.push (e.to);}}} If the cost is INF then abort the charge flow if (d[t] = = INF) return false;cost + = d[t] * A[t];flow + = a[t];ll u = t;while (U! = s) {Edge[p[u]].cap-= A[t];edge[p[u] ^ 1].cap + = A[t];u = Edge[p[u] ^ 1].to;} return true;} ll Flow, Cost;ll Mincost (ll S, ll t) {flow = 0, cost = 0;while (SPFA (S, t, flow, cost)); void Init () {memset (head,-1, sizeof head); edgenum = 0;} int N, m, S, T, from, To;int In[n], Out[n];int main () {int. T, Cas = 1; Rd (T), while (t--) {memset (in, 0, sizeof in); Memset (ou T, 0, sizeof out); Init (); Rd (n); RD (M); RD (s); RD (t); from = 0, to = n + 1;ll now = 0;for (int i = 0, u, V, a, B; i < m; i++) {rd (U); Rd (v); Rd (a); Rd (b); if (a > B) { Now + = B;add (U, V, 1, a-B);} else {now + = A;add (V, U, 1, b-a); in[v]++; out[u]++;}} in[s]++; out[t]++;for (int i = 1; I <= n; i++) {if (In[i] > Out[i]) Add (from, I, in[i]-out[i], 0), else if (In[i] < out[i]) Add (i, to, Out[i]-in[i], 0);} Mincost (from, to);p rintf (' Case%d: ', cas++); for (int i = Head[from]; ~i; i = Edge[i].nex) {if (edge[i].cap) flow =-1;} if (flow = =-1) puts ("impossible"), Else printf ("%d\n", now + cost);} return 0;}
HDU 4067 Random Maze cost flow structure Euler pathway