有源汇有上下界最小流,->上下界网络流
注意细节,边数组也要算上后加到SS,TT边。
1 #include<cstdio>
2 #include<algorithm>
3 #include<cmath>
4 #include<cstring>
5 #include<iostream>
6
7 using namespace std;
8
9 const int N = 150010;
10 const int INF = 1e9;
11
12 struct Edge{
13 int to,nxt,c;
14 }e[500100];
15 int head[N],dis[N],cur[N],M[N];
16 int q[500100],L,R;
17 int tot = 1,n,m,S,T,Sum;
18
19 inline char nc() {
20 static char buf[100000],*p1 = buf,*p2 = buf;
21 return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
22 }
23 inline int read() {
24 int x = 0,f = 1;char ch = nc();
25 for (; ch<'0'||ch>'9';ch=nc()) if(ch=='-') f=-1;
26 for (; ch>='0'&&ch<='9'; ch=nc()) x=x*10+ch-'0';
27 return x * f;
28 }
29 void add_edge(int u,int v,int c) {
30 e[++tot].to = v,e[tot].c = c,e[tot].nxt = head[u],head[u] = tot;
31 }
32 bool bfs() {
33 for (int i=1; i<=n+2; ++i)
34 cur[i] = head[i],dis[i] = -1;
35 L = 1,R = 0;
36 q[++R] = S;
37 dis[S] = 0;
38 while (L <= R) {
39 int u = q[L++];
40 for (int i=head[u]; i; i=e[i].nxt) {
41 int v = e[i].to;
42 if (dis[v] == -1 && e[i].c > 0) {
43 dis[v] = dis[u] + 1;
44 q[++R] = v;
45 if (v == T) return true;
46 }
47 }
48 }
49 return false;
50 }
51 int dfs(int u,int flow) {
52 if (u == T) return flow;
53 int used = 0;
54 for (int &i=cur[u]; i; i=e[i].nxt) {
55 int v = e[i].to;
56 if (dis[v] == dis[u] + 1 && e[i].c > 0) {
57 int tmp = dfs(v,min(e[i].c,flow-used));
58 if (tmp > 0) {
59 e[i].c -= tmp;e[i^1].c += tmp;
60 used += tmp;
61 if (used == flow) break;
62 }
63 }
64 }
65 if (used != flow) dis[u] = -1;
66 return used;
67 }
68 int dinic(int s,int t) {
69 S = s,T = t;
70 int ans = 0;
71 while (bfs()) ans += dfs(S,INF);
72 return ans;
73 }
74 int main () {
75 n = read(),m = read();
76 int s = read(),t = read();
77 int ss = n + 1,tt = n + 2;
78 for (int i=1; i<=m; ++i) {
79 int u = read(),v = read(),b = read(),c = read();
80 add_edge(u,v,c-b);
81 add_edge(v,u,0);
82 M[u] -= b;M[v] += b;
83 }
84 for (int i=1; i<=n; ++i) {
85 if (M[i] > 0) add_edge(ss,i,M[i]),add_edge(i,ss,0),Sum += M[i];
86 if (M[i] < 0) add_edge(i,tt,-M[i]),add_edge(tt,i,0);
87 }
88 add_edge(t,s,INF); //-
89 add_edge(s,t,0);
90 if (dinic(ss,tt) != Sum) {
91 printf("please go home to sleep");
92 return 0;
93 }
94 int ans = e[tot].c;
95 e[tot].c = 0;e[tot ^ 1].c = 0;
96 ans -= dinic(t,s);
97 printf("%d",ans);
98 return 0;
99 }
来源:oschina
链接:https://my.oschina.net/u/4407318/blog/4242058