Hướng dẫn giải của Luồng với chi phí nhỏ nhất
Chỉ dùng lời giải này khi không có ý tưởng, và đừng copy-paste code từ lời giải này. Hãy tôn trọng người ra đề và người viết lời giải.
Nộp một lời giải chính thức trước khi tự giải là một hành động có thể bị ban.
Nộp một lời giải chính thức trước khi tự giải là một hành động có thể bị ban.
Lưu ý: Các code mẫu dưới đây chỉ mang tính tham khảo và có thể không AC được bài tập này
Code mẫu của flashmt
#include <iostream> #include <algorithm> #include <cstdio> #include <cstring> #include <vector> #include <queue> using namespace std; const long long oo = 1LL << 60; struct edge { long long x, y, cap, flow, cost; }; struct MinCostMaxFlow { long long n, S, T; vector < vector <long long> > a; vector <long long> dist, prev, done, pot; vector <edge> e; MinCostMaxFlow() {} MinCostMaxFlow(long long _n, long long _S, long long _T) { n = _n; S = _S; T = _T; a = vector < vector <long long> >(n + 1); dist = vector <long long>(n + 1); prev = vector <long long>(n + 1); done = vector <long long>(n + 1); pot = vector <long long>(n + 1, 0); } void addEdge(long long x, long long y, long long _cap, long long _cost) { edge e1 = {x, y, _cap, 0, _cost}; edge e2 = {y, x, 0, 0, -_cost}; a[x].push_back(e.size()); e.push_back(e1); a[y].push_back(e.size()); e.push_back(e2); } pair <long long,long long> dijkstra() { long long flow = 0, cost = 0; for (long long i = 1; i <= n; i++) done[i] = 0, dist[i] = oo; priority_queue < pair<long long,long long> > q; dist[S] = 0; prev[S] = -1; q.push(make_pair(0, S)); while (!q.empty()) { long long x = q.top().second; q.pop(); if (done[x]) continue; done[x] = 1; for (int i = 0; i < int(a[x].size()); i++) { long long id = a[x][i], y = e[id].y; if (e[id].flow < e[id].cap) { long long D = dist[x] + e[id].cost + pot[x] - pot[y]; if (!done[y] && D < dist[y]) { dist[y] = D; prev[y] = id; q.push(make_pair(-dist[y], y)); } } } } for (long long i = 1; i <= n; i++) pot[i] += dist[i]; if (done[T]) { flow = oo; for (long long id = prev[T]; id >= 0; id = prev[e[id].x]) flow = min(flow, e[id].cap - e[id].flow); for (long long id = prev[T]; id >= 0; id = prev[e[id].x]) { cost += e[id].cost * flow; e[id].flow += flow; e[id ^ 1].flow -= flow; } } return make_pair(flow, cost); } pair <long long,long long> minCostMaxFlow() { long long totalFlow = 0, totalCost = 0; while (1) { pair <long long,long long> u = dijkstra(); if (!done[T]) break; totalFlow += u.first; totalCost += u.second; } return make_pair(totalFlow, totalCost); } }; long long flow[111][111], hasEdge[111][111], c[111][111], cc[111][111]; int main() { //freopen("i.in", "r", stdin); long long n, m, S, T, F, x, y, cap, cost; cin >> n >> m >> F >> S >> T; MinCostMaxFlow u(n + 2, n + 1, n + 2); u.addEdge(n + 1, S, F, 0); u.addEdge(T, n + 2, F, 0); while (m--) { cin >> x >> y >> cost >> cap; hasEdge[x][y] = hasEdge[y][x] = 1; c[x][y] = c[y][x] = cost; cc[x][y] = cc[y][x] = cap; } for (int i = 1; i <= n; i++) for (int j = 1; j <= n; j++) if (cc[i][j] > 0) u.addEdge(i, j, cc[i][j], c[i][j]); pair <long long,long long> ans = u.minCostMaxFlow(); if (ans.first < F) puts("-1"); else { cout << ans.second << endl; for (int i = 0; i < int(u.e.size()); i++) { long long x = u.e[i].x, y = u.e[i].y; if (x > y) continue; flow[x][y] += u.e[i].flow; } for (long long i = 1; i <= n; i++) for (long long j = i + 1; j <= n; j++) if (hasEdge[i][j]) { if (flow[i][j] > 0) cout << i << ' ' << j << ' ' << flow[i][j] << endl; if (flow[i][j] < 0) cout << j << ' ' << i << ' ' << -flow[i][j] << endl; } puts("0 0 0"); } }
Code mẫu của ladpro98
#include <cstring> #include <vector> #include <list> #include <map> #include <set> #include <queue> #include <deque> #include <stack> #include <bitset> #include <algorithm> #include <functional> #include <numeric> #include <utility> #include <sstream> #include <fstream> #include <iostream> #include <iomanip> #include <cstdio> #include <cmath> #include <climits> #include <cstdlib> #include <ctime> #include <memory.h> #include <cassert> #define FOR(i, a, b) for(int i = (a); i < (b); ++i) #define REP(i, a, b) for(int i = (a); i <=(b); ++i) #define FORD(i, a, b) for(int i = (a); i > (b); --i) #define REPD(i, a, b) for(int i = (a); i >=(b); --i) #define TR(it, a) for(__typeof(a.begin()) it = a.begin(); it != a.end(); ++it) #define RESET(a, v) memset(a, (v), sizeof(a)) #define SZ(a) (int(a.size())) #define ALL(a) a.begin(), a.end() #define PB push_back #define MP make_pair #define LL long long #define LD long double #define II pair<int, int> #define X first #define Y second #define VI vector<int> #define VII vector<II> #define endl '\n' const int N = 222; const int INF = INT_MAX; using namespace std; int d[N]; int T[N]; bool inQ[N]; int cap[N][N], cost[N][N], flow[N][N]; int n, m, source, sink; int minCost, maxFlow; bool findPath() { queue<int> Q; REP(i, 1, n) { d[i] = INF; T[i] = 0; inQ[i] = 0; } Q.push(source); inQ[source] = 1; d[source] = 0LL; while (!Q.empty()) { int u = Q.front(); Q.pop(); inQ[u] = 0; REP(v, 1, n) if (flow[u][v] < cap[u][v]) { int uv = (flow[u][v] < 0 ? -1 : 1) * cost[u][v]; if (d[v] > d[u] + uv) { d[v] = d[u] + uv; T[v] = u; if (!inQ[v]) { inQ[v] = 1; Q.push(v); } } } } return T[sink] != 0; } void incFlow() { int delta = INF; for (int v = sink; v != source; v = T[v]) delta = min(delta, flow[T[v]][v] >= 0 ? (cap[T[v]][v] - flow[T[v]][v]) : -flow[T[v]][v]); for (int v = sink; v != source; v = T[v]) flow[T[v]][v] += delta, flow[v][T[v]] -= delta; maxFlow += delta; minCost += d[sink] * delta; } int main() { ios::sync_with_stdio(0); cin.tie(0); #ifdef _LAD_ freopen("9.in", "r", stdin); #endif // _LAD_ cin >> n >> m >> maxFlow >> source >> sink; int u, v; FOR(i, 0, m) { cin >> u >> v; cin >> cost[u][v] >> cap[u][v]; cost[v][u] = cost[u][v]; cap[v][u] = cap[u][v]; } ++n; cost[n][source] = 0; cap[n][source] = maxFlow; int S = maxFlow; source = n; maxFlow = 0; while (findPath()) incFlow(); if (maxFlow < S) cout << -1 << endl; else { cout << minCost << endl; FOR(u, 1, n) FOR(v, 1, n) if (flow[u][v] > 0) cout << u << ' ' << v << ' ' << flow[u][v] << endl; cout << "0 0 0\n"; } return 0; }
Code mẫu của RR
#include <set> #include <map> #include <list> #include <cmath> #include <queue> #include <stack> #include <cstdio> #include <string> #include <vector> #include <cstdlib> #include <cstring> #include <sstream> #include <iomanip> #include <complex> #include <iostream> #include <algorithm> #include <ctime> #include <deque> #include <bitset> #include <cctype> #include <utility> #include <cassert> #define FOR(i,a,b) for(int i=(a),_b=(b); i<=_b; i++) #define FORD(i,a,b) for(int i=(a),_b=(b); i>=_b; i--) #define REP(i,a) for(int i=0,_a=(a); i<_a; i++) #define EACH(it,a) for(__typeof(a.begin()) it = a.begin(); it != a.end(); ++it) #define DEBUG(x) { cout << #x << " = "; cout << (x) << endl; } #define PR(a,n) { cout << #a << " = "; FOR(_,1,n) cout << a[_] << ' '; cout << endl; } #define PR0(a,n) { cout << #a << " = "; REP(_,n) cout << a[_] << ' '; cout << endl; } #define sqr(x) ((x) * (x)) using namespace std; #define prev prev_ const long long F_INF = 1000111000111000LL; const long long C_INF = 1000111000111000LL; template<class Flow = long long, class Cost = long long> struct MinCostFlow { int V, E; vector<Flow> cap; vector<Cost> cost; vector<int> to, prev; vector<Cost> dist, pot; vector<int> last, path, used; priority_queue< pair<Cost, int> > q; MinCostFlow(int V, int E) : V(V), E(0), cap(E*2,0), cost(E*2,0), to(E*2,0), prev(E*2,0), dist(V,0), pot(V,0), last(V, -1), path(V,0), used(V,0) {} int addEdge(int x, int y, Flow f, Cost c) { cap[E] = f; cost[E] = c; to[E] = y; prev[E] = last[x]; last[x] = E; E++; cap[E] = 0; cost[E] = -c; to[E] = x; prev[E] = last[y]; last[y] = E; E++; return E - 2; } pair<Flow, Cost> search(int s, int t) { Flow ansf = 0; Cost ansc = 0; REP(i,V) used[i] = false; REP(i,V) dist[i] = C_INF; dist[s] = 0; path[s] = -1; q.push(make_pair(0, s)); while (!q.empty()) { int x = q.top().second; q.pop(); if (used[x]) continue; used[x] = true; for(int e = last[x]; e >= 0; e = prev[e]) if (cap[e] > 0) { Cost tmp = dist[x] + cost[e] + pot[x] - pot[to[e]]; if (tmp < dist[to[e]] && !used[to[e]]) { dist[to[e]] = tmp; path[to[e]] = e; q.push(make_pair(-dist[to[e]], to[e])); } } } REP(i,V) pot[i] += dist[i]; if (used[t]) { ansf = F_INF; for(int e=path[t]; e >= 0; e=path[to[e^1]]) ansf = min(ansf, cap[e]); for(int e=path[t]; e >= 0; e=path[to[e^1]]) { ansc += cost[e] * ansf; cap[e] -= ansf; cap[e^1] += ansf; } } return make_pair(ansf, ansc); } pair<Flow, Cost> minCostFlow(int s, int t) { Flow ansf = 0; Cost ansc = 0; while (1) { pair<Flow, Cost> p = search(s, t); if (!used[t]) break; ansf += p.first; ansc += p.second; } return make_pair(ansf, ansc); } }; const int MN = 111*111*2; long long f[111][111], c[111][111]; int id_u[MN], id_v[MN], edges[MN]; int main() { int n, m, k, s, t; while (cin >> n >> m >> k >> s >> t) { MinCostFlow<long long, long long> mcf(n+1, m*2+2); mcf.addEdge(0, s, k, 0); memset(f, 0, sizeof f); FOR(i,1,m) { int u, v; cin >> u >> v; cin >> c[u][v] >> f[u][v]; c[v][u] = c[u][v]; f[v][u] = f[u][v]; } m = 0; FOR(i,1,n) FOR(j,i+1,n) if (f[i][j]) { edges[++m] = mcf.addEdge(i, j, f[i][j], c[i][j]); id_u[m] = i; id_v[m] = j; edges[++m] = mcf.addEdge(j, i, f[i][j], c[i][j]); id_u[m] = j; id_v[m] = i; } pair<long long, long long> res = mcf.minCostFlow(0, t); if (res.first < k) { cout << -1 << endl; continue; } cout << res.second << endl; FOR(i,1,m/2) { int u = id_u[i], v = id_v[i]; int f_xuoi = f[u][v] - mcf.cap[edges[i*2-1]]; int f_nguoc = f[v][u] - mcf.cap[edges[i*2]]; int t = min(f_xuoi, f_nguoc); f_xuoi -= t; f_nguoc -= t; if (f_xuoi > 0) { cout << id_u[i*2-1] << ' ' << id_v[i*2-1] << ' ' << f_xuoi << endl; } if (f_nguoc > 0) { cout << id_u[i*2] << ' ' << id_v[i*2] << ' ' << f_nguoc << endl; } } cout << "0 0 0" << endl; } }
Code mẫu của hieult
#include <bits/stdc++.h> using namespace std; typedef long long ll; typedef long double ld; typedef unsigned long long ull; typedef pair <int, int> pii; typedef pair <ll, ll> pll; typedef vector <int> vi; typedef vector <string> vs; #define FOR(i, a, b) for (int i = (a); i <= (b); i++) #define FORD(i, a, b) for (int i = (a); i >= (b); i--) #define FIT(it, v) for (typeof((v).begin())it = (v).begin(); it != (v).end(); ++it) #define FITD(it, v) for (typeof((v).rbegin())it = (v).rbegin(); it != (v).rend(); ++it) #define VAR(a, b) typeof(b) a(b) #define ALL(v) (v).begin(), (v).end() #define SET(a, x) memset((a), (x), sizeof(a)) #define SIZE(a) ((int)(a).size()) #define EXIST(a, b) (find(ALL(a), (b)) != (a).end()) #define SORT(x) sort(ALL(x)) #define GSORT(x) sort(ALL(x), greater<typeof(*((x).begin()))>()) #define UNIQUE(v) SORT(v); (v).resize(unique(ALL(v)) - (v).begin()) #define ENUM(v) FIT(it, (v)) cout << *it << " "; cout << endl #define PF push_front #define PB push_back #define MP make_pair #define F first #define S second // bit operater int BIT(int i,ll x) { return(x&(1<<i));} ll ONBIT(int i,ll x){ return(x|(1<<i));} ll OFFBIT(int i,ll x){return (x& ~(1<<i));} ll FLIPBIT(int i,ll x){return (x^(1<<i));} ll NUMBIT(ll x) {return __builtin_popcount(x);} // math template<class T> T gcd(T a, T b){ T r; while (b != 0) { r = a % b; a = b; b = r; } return a;} template<class T> T lcm(T a, T b) { return a / gcd(a, b) * b; } ll POW(ll x,ll y,ll base) { if (!y) return 1; ll tg=POW(x,y/2,base); tg=(tg*tg)%base; if (y%2) return (tg*x)%base; else return tg; } ull Multy(ull a,ull b,ull base) { if (!a || !b) return 0; if (a<=ULLONG_MAX/b) return(a*b)%base; ull x=Multy(a,b/2,base); x=(x+x)%base; if (b%2==1) x=(x+a)%base; return(x); } ll Com(int k,int n,int base) { if (k==0) return 1; ll x=1,tg=1,y; FOR(i,n-k+1,n) x=(x*i)%base; FOR(i,1,k) tg=(tg*i)%base; y=POW(tg,base-2,base); return(x*y%base); } //int primes[5500000]; //bool nto[10000000]; //int numprime=0; //void sang(ll n) //{ // FOR(i,0,n) nto[i]=true; // nto[1]=false; // nto[0]=false; // for(ll i=2;i<=n;i++) // if (nto[i]) // { // numprime++; // primes[numprime]=i; // for(ll j=i*i;j<=n;j+=i) nto[j]=false; // } //} //ll EulerPhi(ll n) //{ // ll PF_idx=1; // ll PF=primes[PF_idx]; // ll ans=n; // while (PF*PF<=n) // { // if (n%PF==0) ans-=ans/PF; // while (n%PF==0) n/=PF; // PF=primes[++PF_idx]; // } // if (n!=1) ans-=ans/n; // return ans; //} const int maxv=500; const int maxe=maxv*maxv; const int inf = (int)1e9 + 5; const ll linf = (ll)1e16 + 5; const int dr[] = {-1, 0, +1, 0}; const int dc[] = {0, +1, 0, -1}; struct MincostFlow { int n, s, t, E, adj[maxe], next[maxe], last[maxv], which[maxv]; ll totalCost, totalFlow, cap[maxe], flow[maxe], cost[maxe], pot[maxe], dist[maxv]; void init(int _n, int _s, int _t) { n = _n; s = _s; t = _t; SET(last, -1); E = 0; } void add(int u, int v, ll ca, ll co) { adj[E] = v; cap[E] = ca; flow[E] = 0; cost[E] = +co; next[E] = last[u]; last[u] = E++; adj[E] = u; cap[E] = 0; flow[E] = 0; cost[E] = -co; next[E] = last[v]; last[v] = E++; } void bellman() { bool stop = false; SET(pot, 0); while (!stop) { stop = true; FOR(u,0,n-1) for (int e = last[u]; e != -1; e = next[e]) if (flow[e] < cap[e]) { int v = adj[e]; if (pot[v] > pot[u] + cost[e]) { pot[v] = pot[u] + cost[e]; stop = false; } } } } bool dijkstra() { typedef pair<ll, int> node; priority_queue<node, vector<node>, greater<node> > que; FOR(u,0,n-1) dist[u] = linf; dist[s] = 0; que.push(MP(0, s)); while (!que.empty()) { ll dnow = que.top().F; int u = que.top().S; que.pop(); if (dnow > dist[u]) continue; for (int e = last[u]; e != -1; e = next[e]) if (flow[e] < cap[e]) { int v = adj[e]; ll dnext = dnow + cost[e] + pot[u] - pot[v]; if (dist[v] > dnext) { dist[v] = dnext; which[v] = e; que.push(MP(dnext, v)); } } } return dist[t] < linf; } bool maxflow(ll desireFlow = linf) { totalCost = totalFlow = 0; bellman(); while (totalFlow < desireFlow) { if (!dijkstra()) return false; ll delta = desireFlow - totalFlow; for (int v = t, e = which[v]; v != s; v = adj[e ^ 1], e = which[v]) delta = min(delta, cap[e] - flow[e]); for (int v = t, e = which[v]; v != s; v = adj[e ^ 1], e = which[v]) { flow[e] += delta; flow[e ^ 1] -= delta; } totalFlow += delta; totalCost += delta * (dist[t] - pot[s] + pot[t]); FOR(u,0,n-1) pot[u] += dist[u]; } return true; } } mcf; //------------------------ const char IN[] = "_.in"; const char OUT[] = "_.out"; const int maxn=310; const int base=1e9+7; int test; //cout<<setprecision(7)<<fixed<<"Case "<<I<<": " int n,m,k,s,f; int c[maxn][maxn],d[maxn][maxn]; int main() { //freopen(IN, "r", stdin); //freopen(OUT, "w", stdout); int u,v,cost,cap; cin>>n>>m>>k>>s>>f; mcf.init(n+2,0,n+1) ; mcf.add(0,s,k,0); mcf.add(f,n+1,k,0); SET(c,-1); SET(d,-1); FOR(i,0,m-1) { cin>>u>>v>>cost>>cap; c[u][v]=c[v][u]=cost; d[u][v]=d[v][u]=cap; } FOR(i,1,n) FOR(j,i+1,n) if (c[i][j]!=-1) { mcf.add(i,j,d[i][j],c[i][j]); mcf.add(j,i,d[j][i],c[j][i]); } mcf.maxflow(); if (mcf.totalFlow<k) { cout<<-1; return 0; } else { cout<<mcf.totalCost<<endl; FOR(i,0,mcf.E/2) if (mcf.flow[2*i] && mcf.adj[2*i+1]!=0 && mcf.adj[i+i]!=n+1) { cout<<mcf.adj[i*2+1]<<" "<<mcf.adj[i+i]<<" "<<mcf.flow[i+i]<<endl; } cout<<"0 0 0"<<endl; } return 0; }
Code mẫu của ll931110
program MINCOST; const input = ''; output = ''; maxn = 103; var d,c,f: array[1..maxn,1..maxn] of longint; n,m,k,s,t,count: longint; inqueue: array[1..maxn] of boolean; queue: array[0..maxn] of longint; best,trace: array[1..maxn] of longint; front,rear: longint; fi,fo: text; procedure openfile; begin assign(fi, input); reset(fi); assign(fo, output); rewrite(fo); end; procedure init; var i,u,v: longint; begin readln(fi, n, m, k, s, t); fillchar(c, sizeof(c), 0); fillchar(f, sizeof(f), 0); for i := 1 to m do begin readln(fi, u, v, d[u,v], c[u,v]); d[v,u] := d[u,v]; c[v,u] := c[u,v]; end; end; function FindPath: boolean; var u,v,tmp: longint; nt: longint; begin fillchar(trace, sizeof(trace), 0); for u := 1 to n do best[u] := high(longint); best[s] := 0; fillchar(inqueue, sizeof(inqueue), false); inqueue[s] := true; nt := 1; front := 1; rear := 1; queue[1] := s; repeat u := queue[front]; front := (front + 1) mod maxn; inqueue[u] := false; dec(nt); for v := 1 to n do if c[u,v] > f[u,v] then begin if f[u,v] = 0 then tmp := d[u,v] else tmp := d[u,v] * f[u,v] div abs(f[u,v]); if best[v] > best[u] + tmp then begin best[v] := best[u] + tmp; trace[v] := u; if not inqueue[v] then begin inqueue[v] := true; inc(nt); rear := (rear + 1) mod maxn; queue[rear] := v; end; end; end; until nt = 0; FindPath := (best[t] < high(longint)); end; procedure IncFlow; var u,v,p: longint; delta: longint; begin delta := high(longint); v := t; while v <> s do begin u := trace[v]; if f[u,v] >= 0 then p := c[u,v] - f[u,v] else p := f[v,u]; if delta > p then delta := p; v := u; end; if delta > k - count then delta := k - count; count := count + delta; v := t; while v <> s do begin u := trace[v]; f[u,v] := f[u,v] + delta; f[v,u] := f[v,u] - delta; v := u; end; end; procedure solve; begin count := 0; repeat if not FindPath then break; IncFlow; until count = k; end; procedure printresult; var i,j,cost: longint; begin if count < k then writeln(fo, -1) else begin cost := 0; for i := 1 to n do for j := 1 to n do if f[i,j] > 0 then cost := cost + d[i,j] * f[i,j]; writeln(fo, cost); for i := 1 to n do for j := 1 to n do if f[i,j] > 0 then writeln(fo, i, ' ', j, ' ', f[i,j]); writeln(fo, 0, ' ', 0, ' ', 0); end; end; procedure closefile; begin close(fo); close(fi); end; begin openfile; init; solve; printresult; closefile; end.
Code mẫu của skyvn97
#include<bits/stdc++.h> #define MAX 111 #define FOR(i,a,b) for (int i=(a);i<=(b);i=i+1) #define REP(i,n) for (int i=0;i<(n);i=i+1) #define FORE(i,v) for (__typeof((v).begin()) i=(v).begin();i!=(v).end();i++) #define fi first #define se second using namespace std; const int INF=(int)1e9+7; typedef pair<int,int> ii; void minimize(int &x,const int &y) { if (x>y) x=y; } class MaxFlowMinCost { public: struct edge { int from,to,capa,flow,cost; edge() { from=0;to=0;capa=0;flow=0;cost=0; } edge(int u,int v,int ca,int co) { from=u;to=v;capa=ca;flow=0;cost=co; } int residual(void) const { return (capa-flow); } }; vector<vector<int> > g; vector<edge> e; vector<int> d,tr; int n; MaxFlowMinCost() { n=0; } MaxFlowMinCost(int n) { this->n=n; g.assign(n+7,vector<int>()); e.clear(); d=vector<int>(n+7); tr=vector<int>(n+7); } void addedge(int u,int v,int ca,int co) { g[u].push_back(e.size()); e.push_back(edge(u,v,ca,co)); g[v].push_back(e.size()); e.push_back(edge(v,u,0,-co)); } bool FordBellman(int s,int t) { FOR(i,1,n) { d[i]=INF; tr[i]=-1; } vector<bool> inq=vector<bool>(n+7,false); queue<int> q; while (!q.empty()) q.pop(); q.push(s);inq[s]=true;d[s]=0; while (!q.empty()) { int u=q.front();q.pop();inq[u]=false; FORE(it,g[u]) if (e[*it].residual()>0) { int v=e[*it].to; if (d[v]>d[u]+e[*it].cost) { d[v]=d[u]+e[*it].cost; tr[v]=*it; if (!inq[v]) { q.push(v); inq[v]=true; } } } } return (d[t]<INF); } ii getflow(int s,int t) { int totflow=0; int totcost=0; while (FordBellman(s,t)) { int delta=INF; for (int u=t;u!=s;u=e[tr[u]].from) minimize(delta,e[tr[u]].residual()); for (int u=t;u!=s;u=e[tr[u]].from) { e[tr[u]].flow+=delta; e[tr[u]^1].flow-=delta; } totflow+=delta; totcost+=delta*d[t]; } return (ii(totflow,totcost)); } }; int capa[MAX][MAX],cost[MAX][MAX]; int n,m,k,s,t; MaxFlowMinCost g; void loadgraph(void) { scanf("%d",&n); scanf("%d",&m); scanf("%d",&k); scanf("%d",&s); scanf("%d",&t); memset(capa,-1,sizeof capa); REP(i,m) { int u,v,c,d; scanf("%d",&u); scanf("%d",&v); scanf("%d",&c); scanf("%d",&d); capa[u][v]=d; cost[u][v]=c; capa[v][u]=d; cost[v][u]=c; } g=MaxFlowMinCost(n+1); FOR(u,1,n) FOR(v,1,n) if (capa[u][v]>=0) g.addedge(u,v,capa[u][v],cost[u][v]); g.addedge(n+1,s,k,0); } void process(void) { ii res=g.getflow(n+1,t); if (res.fi<k) { printf("-1"); return; } printf("%d\n",res.se); int totcost=0; REP(i,g.e.size()) if (i%2==0 && g.e[i].flow>0) { if (g.e[i].from<=n) printf("%d %d %d\n",g.e[i].from,g.e[i].to,g.e[i].flow); totcost+=g.e[i].cost*g.e[i].flow; } assert(res==ii(k,totcost)); printf("0 0 0"); } int main(void) { #ifndef ONLINE_JUDGE freopen("tmp.txt","r",stdin); printf("START\n"); #endif loadgraph(); process(); return 0; }
Code mẫu của khuc_tuan
#include "stdio.h" #include "string.h" int n, flow, start, finish, m; int cap[111][111], cost[111][111], f[111][111]; int fx[111], dt; bool visited[111], daxong; bool dfs(int i) { if(daxong) return false; visited[i] = true; if(i==finish) { --flow; return daxong = true; } for(int j=1;j<=n;++j) { if(f[i][j]<cap[i][j] && !visited[j]) { if(fx[i]+cost[i][j]-fx[j]==0) { if(dfs(j)) { ++f[i][j]; return true; } } else dt <?= fx[i]+cost[i][j]-fx[j]; } if(f[j][i]>0 && !visited[j]) { if(fx[j]+cost[j][i]-fx[i]==0) { if(dfs(j)) { --f[j][i]; return true; } } else dt <?= -(fx[j]+cost[j][i]-fx[i]); } } return false; } int main() { int u, v, c, d; scanf("%d%d%d%d%d",&n,&m,&flow,&start,&finish); for(int i=0;i<m;++i) { scanf("%d%d%d%d",&u,&v,&c,&d); cap[u][v] = cap[v][u] = d; cost[u][v] = cost[v][u] = c; } for(int i=0;i<50000 && flow>0;++i) { memset( visited, false, sizeof(visited)); daxong = false; dt = 1000000000; if(!dfs(start)) for(int i=1;i<=n;++i) if(!visited[i]) fx[i] += dt; } if(flow>0) printf("-1"); else { int res = 0; for(int i=1;i<=n;++i) for(int j=1;j<=n;++j) res += f[i][j] * cost[i][j]; printf("%d\n",res); for(int i=1;i<=n;++i) for(int j=1;j<=n;++j) if(f[i][j]>0) printf("%d %d %d\n",i, j, f[i][j]); printf("0 0 0"); } return 0; }
Bình luận