首页 > 代码库 > 最小费用最大流

最小费用最大流

洛谷模板题

没什么好说的,用spfa来找增广路。

技术分享
  1 #include <cstdio>
  2 #include <cstring>
  3 #include <queue>
  4 
  5 using namespace std;
  6 
  7 const int INF = 1 << 26;
  8 int n, m, s, t, cnt;
  9 int to[100001], val[100001], next[100001], cost[100001], head[5001], pre[5001], path[5001], dis[5001];
 10 //pre记录前一个节点,path记录边 
 11 bool vis[5001];
 12 
 13 inline int read()//读入优化 
 14 {
 15     int x = 0, f = 1;
 16     char ch = getchar();
 17     while(ch < 0 || ch > 9)
 18     {
 19         if(ch == -) f = -1;
 20         ch = getchar();
 21     }
 22     while(ch >= 0 && ch <= 9)
 23     {
 24         x = x * 10 + ch - 0;
 25         ch = getchar();
 26     }
 27     return x * f;
 28 }
 29 
 30 inline void add(int a, int b, int c, int d)
 31 {
 32     to[cnt] = b;
 33     val[cnt] = c;
 34     cost[cnt] = d;
 35     next[cnt] = head[a];
 36     head[a] = cnt++;
 37 }
 38 
 39 inline bool spfa()
 40 {
 41     int u, i, v;
 42     memset(vis, 0, sizeof(vis));
 43     memset(pre, -1, sizeof(pre));
 44     for(i = 1; i <= n; i++) dis[i] = INF;
 45     dis[s] = 0;
 46     queue <int> q;
 47     q.push(s);
 48     vis[s] = 1;
 49     while(!q.empty())
 50     {
 51         u = q.front();
 52         vis[u] = 0;
 53         q.pop();
 54         for(i = head[u]; i != -1; i = next[i])
 55         {
 56             v = to[i];
 57             if(val[i] > 0 && dis[v] > dis[u] + cost[i])
 58             {
 59                 dis[v] = dis[u] + cost[i];
 60                 pre[v] = u;
 61                 path[v] = i;
 62                 if(!vis[v])
 63                 {
 64                     q.push(v);
 65                     vis[v] = 1;
 66                 }
 67             }
 68         }
 69     }
 70     return pre[t] != -1;
 71 }
 72 
 73 int main()
 74 {
 75     int i, j, a, b, c, d, money = 0, flow = 0, f;
 76     n = read();
 77     m = read();
 78     s = read();
 79     t = read();
 80     memset(head, -1, sizeof(head));
 81     for(i = 1; i <= m; i++)
 82     {
 83         a = read();
 84         b = read();
 85         c = read();
 86         d = read();
 87         add(a, b, c, d);
 88         add(b, a, 0, -d);
 89     }
 90     while(spfa())
 91     {
 92         f = INF;
 93         for(i = t; i != s; i = pre[i]) f = min(f, val[path[i]]);
 94         flow += f;
 95         money += dis[t] * f;
 96         for(i = t; i != s; i = pre[i])
 97         {
 98             val[path[i]] -= f;
 99             val[path[i] ^ 1] += f;
100         }
101     }
102     printf("%d %d", flow, money);
103     return 0;
104 }
View Code

还有dijkstra+heap优化,暂时没学,晚上再弄。

最小费用最大流