1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
| #include <bits/stdc++.h> using namespace std; const int N = 2e2 + 5; typedef long long ll; const ll llinf = 0x3f3f3f3f3f3f3f3f; int n,m,S,T; int num[N]; namespace Flow{ const int N = 2e3 + 5,M = 2e6 + 5; int fir[N],nxt[M],to[M],w[M],cost[M],ect = 1; inline void addedge(int u1,int v1,int w1,int c1) { nxt[++ect] = fir[u1];fir[u1] = ect;to[ect] = v1;w[ect] = w1;cost[ect] = c1;} inline void ins(int u1,int v1,int w1,int c1) { addedge(u1,v1,w1,c1);addedge(v1,u1,0,-c1);} ll dis[N],h[N]; bool vst[N]; int tot; inline void Clr(int _n) { tot = _n;ect = 1; for(int i = 1;i <= tot;i++) fir[i] = 0; } void spfa(int S,int T) { for(int i = 1;i <= tot;i++) dis[i] = llinf,vst[i] = 0; queue<int> Q; Q.push(S);dis[S] = 0;vst[S] = 1; while(!Q.empty()) { int x = Q.front();Q.pop();vst[x] = 0; for(int i = fir[x],y;y = to[i],i;i = nxt[i]) if(w[i] && dis[y] > dis[x] + cost[i]) { dis[y] = dis[x] + cost[i]; if(!vst[y]) Q.push(y),vst[y] = true; } } for(int i = 1;i <= tot;i++) h[i] = dis[i]; } int pn[N],pe[N],flow[N]; struct node{ int id;ll dis; node(){} node(const int _id,const ll _dis):id(_id),dis(_dis){} bool operator < (const node &rhs) const { return dis > rhs.dis;} }; bool Dijkstra(int S,int T,int F = 1e9) { for(int i = 1;i <= tot;i++) pe[i] = pn[i] = vst[i] = 0,dis[i] = llinf; priority_queue<node> Q; flow[S] = F;Q.emplace(S,dis[S] = 0); while(!Q.empty()) { int x = Q.top().id;Q.pop(); if(vst[x]) continue; vst[x] = true; for(int i = fir[x],y,ww;y = to[i],ww = cost[i] + h[x] - h[y],i;i = nxt[i]) if(w[i] && dis[y] > dis[x] + ww) { dis[y] = dis[x] + ww; pn[y] = x;pe[y] = i;flow[y] = min(flow[x],w[i]); Q.emplace(y,dis[y]); } } return dis[T] < llinf; } pair<ll,ll> MCMF(int S,int T) { ll F = 0,res = 0; spfa(S,T); while(Dijkstra(S,T)) { for(int i = 1;i <= tot;i++) if(vst[i]) h[i] += dis[i]; int now = T; res += flow[T] * h[T]; while(now != S) w[pe[now]] -= flow[T],w[pe[now] ^ 1] += flow[T],now = pn[now]; F += flow[T]; } return make_pair(F,res); } } ll ans = 0; int main() { cin >> n >> m >> S >> T; Flow::Clr(n + 2); for(int i = 1;i <= m;i++) { int x,y,f,c; cin >> x >> y >> f >> c; if(c >= 0) Flow::ins(x,y,f,c); else { num[x] -= f;num[y] += f; Flow::ins(y,x,f,-c); ans += 1ll * c * f; } } int SS = n + 1,TT = n + 2; for(int i = 1;i <= n;i++) { if(num[i] > 0) Flow::ins(SS,i,num[i],0); if(num[i] < 0) Flow::ins(i,TT,-num[i],0); } ans += Flow::MCMF(SS,TT).second; pair<ll,ll> res = Flow::MCMF(S,T); cout << res.first << ' ' << res.second + ans << endl; return 0; }
|