• 【模板】最小费用最大流


    洛谷模板题

    没什么好说的,用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

    但是spfa对于稠密图的处理效果不是很好,所以改用dijkstra+stl堆优化,至少快了些。。

    ——代码

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <queue>
     4 #define Heap pair<int, int>
     5 
     6 using namespace std;
     7 
     8 const int INF = 1 << 26;
     9 int n, m, s, t, cnt;
    10 int to[100001], val[100001], next[100001], cost[100001], head[5001], pre[5001], path[5001], dis[5001];
    11 //pre记录前一个节点,path记录边 
    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 bool Dijkstra()
    40 {
    41     int i, v;
    42     Heap u;
    43     memset(pre, -1, sizeof(pre));
    44     for(i = 1; i <= n; i++) dis[i] = INF;
    45     dis[s] = 0;
    46     priority_queue <Heap, vector <Heap>, greater <Heap> > q;
    47     q.push(make_pair(0, s));//前一个表示当前节点到起点的距离,后一个是当前节点 
    48     while(!q.empty())
    49     {
    50         u = q.top();
    51         q.pop();
    52         if(u.first != dis[u.second]) continue; 
    53         for(i = head[u.second]; i != -1; i = next[i])
    54         {
    55             v = to[i];
    56             if(val[i] > 0 && dis[v] > dis[u.second] + cost[i])
    57             {
    58                 dis[v] = dis[u.second] + cost[i];
    59                 pre[v] = u.second;
    60                 path[v] = i;
    61                 q.push(make_pair(dis[v], v));
    62             }
    63         }
    64     }
    65     return pre[t] != -1;
    66 }
    67 
    68 int main()
    69 {
    70     int i, j, a, b, c, d, money = 0, flow = 0, f;
    71     n = read();
    72     m = read();
    73     s = read();
    74     t = read();
    75     memset(head, -1, sizeof(head));
    76     for(i = 1; i <= m; i++)
    77     {
    78         a = read();
    79         b = read();
    80         c = read();
    81         d = read();
    82         add(a, b, c, d);
    83         add(b, a, 0, -d);
    84     }
    85     while(Dijkstra())
    86     {
    87         f = INF;
    88         for(i = t; i != s; i = pre[i]) f = min(f, val[path[i]]);
    89         flow += f;
    90         money += dis[t] * f;
    91         for(i = t; i != s; i = pre[i])
    92         {
    93             val[path[i]] -= f;
    94             val[path[i] ^ 1] += f;
    95         }
    96     }
    97     printf("%d %d", flow, money);
    98     return 0;
    99 }
    View Code

    洛谷改了数据之后dijk居然T了。。

  • 相关阅读:
    DebugView使用技巧
    网络抓包--Wireshark
    常用curl命令
    chrome.debugger
    修改php.ini 的timezone
    初识Elasticsearch,bulk 操作的遇到的那些事
    chrome 扩展 调试
    sqlite 时间戳转时间
    centos 升级sqlite3
    php 安装redis
  • 原文地址:https://www.cnblogs.com/zhenghaotian/p/6690154.html
Copyright © 2020-2023  润新知