• 最小费用最大流


    https://www.luogu.org/problemnew/show/P3381

    1.SPFA

      1 #include <cstdio>
      2 #include <cstdlib>
      3 #include <cmath>
      4 #include <ctime>
      5 #include <cstring>
      6 #include <string>
      7 #include <map>
      8 #include <set>
      9 #include <list>
     10 #include <queue>
     11 #include <stack>
     12 #include <vector>
     13 #include <bitset>
     14 #include <algorithm>
     15 #include <iostream>
     16 using namespace std;
     17 #define ll long long
     18 const int maxn=5e3+10;
     19 const int inf=1e9;
     20 
     21 struct node
     22 {
     23     int d,len;
     24     ll cost;
     25     node *next,*opp;
     26 }*e[maxn],*pre[maxn];
     27 
     28 int flow=0,s,t,add[maxn];
     29 ll fee=0,dist[maxn];
     30 queue<int> st;
     31 bool vis[maxn];
     32 
     33 void add_edge(int x,int y,int len,ll cost)
     34 {
     35     node *p1=(node*) malloc (sizeof(node));
     36     node *p2=(node*) malloc (sizeof(node));
     37 
     38     p1->d=y;
     39     p1->len=len;
     40     p1->cost=cost;
     41     p1->next=e[x];
     42     p1->opp=p2;
     43     e[x]=p1;
     44 
     45     p2->d=x;///注意
     46     p2->len=0;///注意
     47     p2->cost=-cost;///注意
     48     p2->next=e[y];
     49     p2->opp=p1;
     50     e[y]=p2;
     51 }
     52 
     53 ///可证明此方法能找到最大流,同时这是方式是费用最小的
     54 
     55 void bfs()
     56 {
     57     int d,dd;
     58     node *p;
     59     while (1)
     60     {
     61         memset(dist,0x7f,sizeof(dist));
     62         memset(add,0,sizeof(add));
     63         dist[s]=0;
     64         add[s]=inf; vis[s]=1;
     65         st.push(s);
     66         while (!st.empty())
     67         {
     68             ///保证能扩展的点,add[d]>0
     69             d=st.front();
     70             st.pop();
     71             p=e[d];
     72             while (p)
     73             {
     74                 dd=p->d;
     75                 if (p->len>0 && dist[dd]>dist[d]+p->cost)///注意
     76                 {
     77                     dist[dd]=dist[d]+p->cost;
     78                     add[dd]=min(add[d],p->len);
     79                     pre[dd]=p->opp;
     80                     if (!vis[dd])
     81                     {
     82                         vis[dd]=1;
     83                         st.push(dd);
     84                     }
     85                 }
     86                 p=p->next;
     87             }
     88             vis[d]=0;///
     89         }
     90 
     91         if (add[t]==0)
     92             break;
     93 
     94         flow+=add[t];
     95         fee+=add[t]*dist[t];
     96         d=t;
     97         while (d!=s)
     98         {
     99             pre[d]->len+=add[t];///
    100             pre[d]->opp->len-=add[t];
    101             d=pre[d]->d;
    102         }
    103     }
    104 }
    105 
    106 int main()
    107 {
    108     int n,m,x,y,z;
    109     ll w;
    110     scanf("%d%d%d%d",&n,&m,&s,&t);
    111     while (m--)
    112     {
    113         scanf("%d%d%d%lld",&x,&y,&z,&w);
    114         add_edge(x,y,z,w);
    115     }
    116     bfs();
    117     printf("%d %lld",flow,fee);
    118     return 0;
    119 }

    2.BellmanFord TLE

     1 /**
     2 BellmanFord TLE
     3 **/
     4 #include <cstdio>
     5 #include <cstdlib>
     6 #include <cmath>
     7 #include <cstring>
     8 #include <time.h>
     9 #include <string>
    10 #include <set>
    11 #include <map>
    12 #include <list>
    13 #include <stack>
    14 #include <queue>
    15 #include <vector>
    16 #include <bitset>
    17 #include <ext/rope>
    18 #include <algorithm>
    19 #include <iostream>
    20 using namespace std;
    21 #define ll long long
    22 #define minv 1e-6
    23 #define inf 1e18
    24 #define pi 3.1415926536
    25 #define nl 2.7182818284
    26 const ll mod=1e9+7;//998244353
    27 const int maxn=5e3+10;
    28 const int maxm=5e4+10;
    29 
    30 struct node
    31 {
    32     int x,y;
    33     ll len,fee;
    34 }e[maxm<<1];
    35 
    36 int n,m,s,t,pre[maxn];
    37 ll flow=0,fee=0,add[maxn],dist[maxn];
    38 
    39 bool bell()
    40 {
    41     bool v=0;
    42     int i;
    43     for (i=1;i<=m;i++)
    44         if (dist[e[i].y]>dist[e[i].x]+e[i].fee && e[i].len>0)
    45         {
    46             dist[e[i].y]=dist[e[i].x]+e[i].fee;
    47             add[e[i].y]=min(add[e[i].x],e[i].len);
    48             pre[e[i].y]=i;
    49             v=1;
    50         }
    51     return v;
    52 }
    53 
    54 void change()
    55 {
    56     int d;
    57     flow+=add[t];
    58     fee+=1ll*dist[t]*add[t];
    59     d=t;
    60     while (d!=s)
    61     {
    62         e[pre[d]].len-=add[t];
    63         if (pre[d] & 1)
    64             e[pre[d]+1].len+=add[t];
    65         else
    66             e[pre[d]-1].len+=add[t];
    67         d=e[pre[d]].x;
    68     }
    69 }
    70 
    71 int main()
    72 {
    73     int i;
    74     scanf("%d%d%d%d",&n,&m,&s,&t);
    75     m<<=1;
    76     for (i=1;i<=m;i+=2)
    77     {
    78         scanf("%d%d%lld%lld",&e[i].x,&e[i].y,&e[i].len,&e[i].fee);
    79         e[i+1].x=e[i].y;
    80         e[i+1].y=e[i].x;
    81         e[i+1].len=0;
    82         e[i+1].fee=-e[i].fee;
    83     }
    84     add[s]=inf;
    85     while (1)
    86     {
    87         fill(dist+1,dist+n+1,inf);
    88         dist[s]=0;
    89         add[t]=0;
    90         for (i=1;i<=n;i++)
    91             if (!bell() && add[t]!=0)
    92                 break;
    93         if (i==n+1)
    94             break;
    95         change();
    96     }
    97     printf("%lld %lld",flow,fee);
    98     return 0;
    99 }

    3.有负边,不能用Dijkstra。

  • 相关阅读:
    Elasticsearch节点下线(退役)and unassigned shards
    详解Hbase架构原理
    docker安装(yum方式)
    矩形的逆时针蛇形填数
    CentOS7安装iptables防火墙
    Linux:-bash: ***: command not found
    两个大数相乘JAVA版
    SQL Server 2012时出现命名管道提供程序: 无法打开与 SQL Server 的连接
    jstl函数库及自定义函数库
    This Android SDK requires Android Developer Toolkit version 23.0.0 or above
  • 原文地址:https://www.cnblogs.com/cmyg/p/9569556.html
Copyright © 2020-2023  润新知