【luogu P3381 最小费用最大流】 模板

题目链接:https://www.luogu.org/problemnew/show/P3381

把bfs变成spfa

 1 #include <cstdio>
 2 #include <iostream>
 3 #include <algorithm>
 4 #include <cstring>
 5 #include <queue>
 6 using namespace std;
 7 const int maxn = 1000010;
 8 int maxflow, mincost, dist[maxn], flow[maxn], pre[maxn], last[maxn], n, m, s, t;//flow每条路径的流量,dist每条可行流的最短路
 9 bool vis[maxn];
10 struct EDGE{
11     int to, next, dis, flow;//flow流量 dis花费 
12 }edg[maxn];
13 int head[maxn], cnt = -1;
14 queue<int> q;
15 void add(int u, int v, int w, int c)
16 {
17     edg[++cnt].next = head[u];
18     edg[cnt].flow = w;
19     edg[cnt].to = v;
20     edg[cnt].dis = c;
21     head[u] = cnt;
22 
23     edg[++cnt].next = head[v];
24     edg[cnt].flow = 0;
25     edg[cnt].to = u;
26     edg[cnt].dis = -c;
27     head[v] = cnt;
28 }
29 bool SPFA(int s, int t)
30 {
31     memset(dist,0x7f,sizeof(dist));
32     memset(flow,0x7f,sizeof(flow));
33     memset(vis,0,sizeof(vis));
34     q.push(s); pre[t] = -1; vis[s] = 1; dist[s] = 0;
35     while(!q.empty())
36     {
37         int now = q.front();
38         q.pop();
39         vis[now] = 0;
40         for(int i = head[now]; i != -1; i = edg[i].next)
41         {
42             if(edg[i].flow > 0 && dist[edg[i].to] > dist[now] + edg[i].dis)
43             {
44                 dist[edg[i].to] = dist[now] + edg[i].dis;
45                 pre[edg[i].to] = now;
46                 last[edg[i].to] = i;
47                 flow[edg[i].to] = min(flow[now], edg[i].flow);
48                 if(!vis[edg[i].to])
49                 {
50                     vis[edg[i].to] = 1;
51                     q.push(edg[i].to);
52                 }
53             }
54         }
55     }
56     return pre[t] != -1;
57 }
58 void dfs(int s, int t)
59 {
60     while(SPFA(s,t))
61     {
62         int now = t;
63         maxflow += flow[t];
64         mincost += flow[t]*dist[t];
65         while(now != s)
66         {
67             edg[last[now]].flow -= flow[t];
68             edg[last[now]^1].flow += flow[t];
69             now = pre[now];
70         }
71     }
72 }
73 int main()
74 {
75     memset(head,-1,sizeof(head));
76     scanf("%d%d%d%d",&n,&m,&s,&t);
77     for(int i = 1; i <= m; i++)
78     {
79         int u,v,w,c;
80         scanf("%d%d%d%d",&u,&v,&w,&c);
81         add(u,v,w,c);
82     }
83     dfs(s,t);
84     printf("%d %d",maxflow,mincost);
85     return 0;
86 }

猜你喜欢

转载自www.cnblogs.com/MisakaAzusa/p/9047834.html