Editorial for Hai đường đi (version 2)
Remember to use this editorial only when stuck, and not to copy-paste code from it. Please be respectful to the problem author and editorialist.
Submitting an official solution before solving the problem yourself is a bannable offence.
Submitting an official solution before solving the problem yourself is a bannable offence.
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 ladpro98
#include <bits/stdc++.h> const int N = 400005; const long long INF = (long long)1e18; using namespace std; struct edge { int u, v, w; int cap, flow; edge() { flow = 0; } edge(int _u, int _v, int _w, int _cap) { u = _u; v = _v; w = _w; cap = _cap; flow = 0; } int getAdj(int _u) { return u ^ v ^ _u; } int getCost() { return flow < 0 ? -w : w; } int getResidualFlow() { return flow < 0 ? -flow : (cap - flow); } } E[N]; int nEdge; int n, m, source, sink; bool inQ[N]; long long d[N]; int maxFlow; long long minCost; bool was[N]; int T[N]; vector<int> a[N]; void addEdge(int u, int v, int w) { assert(!(nEdge & 1)); E[nEdge] = edge(u, v, w, 1); E[nEdge | 1] = edge(v, u, w, 1); a[u].push_back(nEdge); a[v].push_back(nEdge | 1); nEdge += 2; } bool findPath() { queue<int> Q; for (int i = 1; i <= n; ++i) d[i] = INF; d[source] = 0; Q.push(source); inQ[source] = 1; while (!Q.empty()) { int u = Q.front(); Q.pop(); inQ[u] = 0; for (vector<int>::iterator it = a[u].begin(); it != a[u].end(); ++it) { if (E[*it].cap > E[*it].flow) { int cost = E[*it].getCost(); int v = E[*it].getAdj(u); if (d[v] > d[u] + cost) { T[v] = *it; d[v] = d[u] + cost; if (!inQ[v]) { inQ[v] = 1; Q.push(v); } } } } } return d[sink] < INF; } void incFlow() { for (int v = sink; v != source; v = E[T[v]].getAdj(v)) ++E[T[v]].flow, --E[T[v] ^ 1].flow; ++maxFlow; minCost += d[sink]; } int main() { ios::sync_with_stdio(0); cin.tie(0); int s, f; cin >> n >> m >> s >> f; int u, v, w; for (int i = 0; i < m; ++i) { cin >> u >> v >> w; addEdge(u, v, w); } source = n + 1; sink = f; addEdge(source, s, 0); addEdge(source, s, 0); ++n; for (int i = 1; i <= n; ++i) random_shuffle(a[i].begin(), a[i].end()); while (maxFlow < 2 && findPath()) incFlow(); if (maxFlow < 2) cout << -1 << endl; else cout << minCost << endl; return 0; }
Code mẫu của RR
//Written by RR {$MODE OBJFPC} uses math; const FINP = ''; FOUT = ''; MAXN = 50111; type list = ^node; node = record u : longint; c : int64; next : list; rev : list; end; var f1,f2 : text; ke : array[1..MAXN] of list; n,s,t : longint; first,last,spt: longint; queue,trace : array[1..MAXN] of longint; d : array[1..MAXN] of int64; inq : array[1..MAXN] of boolean; tr,tr2 : array[1..MAXN] of list; hpos,h : array[1..MAXN] of longint; procedure openF; begin assign(f1,FINP); reset(f1); assign(f2,FOUT); rewrite(f2); end; procedure closeF; begin close(f1); close(f2); end; procedure add(u:longint; c:int64; var a:list); inline; var p:list; begin new(p); p^.u:=u; p^.c:=c; p^.next:=a; a:=p; end; procedure inp; var i,m,u,v:longint; c:int64; begin read(f1,n,m); read(f1,s,t); for i:=1 to m do begin read(f1,u,v,c); add(u,c,ke[v]); add(v,c,ke[u]); ke[u]^.rev:=ke[v]; ke[v]^.rev:=ke[u]; end; end; procedure findPath; var u,v:longint; c:int64; p,q:list; begin fillchar(d,sizeof(d),$77); d[s]:=0; fillchar(inq,sizeof(inq),false); first:=1; last:=1; queue[1]:=s; spt:=1; inq[s]:=true; while spt>0 do begin u:=queue[first]; inc(first); if first=MAXN then first:=1; dec(spt); inq[u]:=false; p:=ke[u]; while p<>nil do begin v:=p^.u; c:=p^.c; q:=p^.rev; if v<>0 then if d[v]>d[u]+c then begin d[v]:=d[u]+c; trace[v]:=u; tr[v]:=q; tr2[v]:=p; if inq[v]=false then begin inc(last); if last=MAXN then last:=1; inc(spt); inq[v]:=true; queue[last]:=v; end; end; //d[v]>d[u]+c p:=p^.next; end; //while p<>nil end; //while spt>0 end; procedure truyVet; var u,v:longint; p:list; begin v:=t; while v<>s do begin u:=trace[v]; p:=tr[v]; p^.c:=-p^.c; p:=tr2[v]; p^.u:=0; v:=u; end; end; procedure solve; var res:int64; begin findPath; res:=d[t]; if res>high(int64) div 2 then begin writeln(f2,-1); exit; end; truyVet; findPath; res:=res+d[t]; if res>high(int64) div 2 then begin writeln(f2,-1); exit; end; writeln(f2,res); end; begin openF; inp; solve; closeF; end.
Comments