【模板】费用流

 1 // luogu-judger time:1341ms
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<cstring>
 5 #include<cmath>
 6 #include<queue>
 7 using namespace std;
 8 typedef long long ll;
 9 #define ms(a,b) memset(a,b,sizeof a)
10 #define inf 2147483647
11 #define rep(i,a,n) for(int i = a;i <= n;i++)
12 #define per(i,n,a) for(int i = n;i >= a;i--)
13 ll read() {
14     ll as = 0,fu = 1;
15     char c = getchar();
16     while(c < '0' || c > '9') {
17         if(c == '-') fu = -1;
18         c = getchar();
19     }
20     while(c >= '0' && c <= '9') {
21         as = as * 10 + c - '0';
22         c = getchar();
23     }
24     return as * fu;
25 }
26 const int N = 100005;
27 //head
28 int n,m,s,t;
29 ll maxx,minn;
30 
31 ll cst[N],flw[N];
32 int head[N],mo[N],nxt[N],cnt = 1;
33 inline void add(int x,int y,ll z,ll f) {
34     mo[++cnt] = y;
35     cst[cnt] = z;
36     flw[cnt] = f;
37     nxt[cnt] = head[x];
38     head[x] = cnt;
39     return;
40 }
41 
42 ll dis[N],flow[N];
43 int pre[N],lst[N];
44 bool vis[N];
45 queue<int> q;
46 bool spfa() {
47     ms(dis,70);
48     ms(flow,70);
49     ms(vis,0);
50     q.push(s);
51     vis[s] = 1,dis[s] = 0;
52     pre[t] = 0;
53     while(!q.empty()) {
54         int x = q.front();
55         q.pop();
56         vis[x] = 0;
57         for(int i = head[x];i;i = nxt[i]) {
58             if(!flw[i]) continue;            
59             int sn = mo[i];
60             if(dis[sn] > dis[x] + cst[i]) {
61                 dis[sn] = dis[x] + cst[i];
62                 pre[sn] = x,lst[sn] = i;
63                 flow[sn] = min(flow[x],flw[i]);
64                 if(!vis[sn]) vis[sn] = 1,q.push(sn);
65             }
66         }
67     }
68     return pre[t];
69 }
70 
71 
72 int main() {
73     n = read();
74     m = read();
75     s = read();
76     t = read();
77     rep(i,1,m) {
78         int x = read();
79         int y = read();
80         ll f = read();
81         ll z = read();
82         add(x,y,z,f);
83         add(y,x,-z,0);
84     }
85     while(spfa()) {
86         int x = t;
87         maxx += flow[t];
88         minn += flow[t] * dis[t];
89         while(x != s) {
90             int nxte = lst[x];
91             flw[nxte] -= flow[t];
92             flw[nxte^1] += flow[t];
93             x = pre[x];
94         }
95     }
96     printf("%lld %lld\n",maxx,minn);
97     return 0;
98 }

 

posted @ 2018-10-03 22:25  白怀潇  阅读(118)  评论(0)    收藏  举报