zoukankan      html  css  js  c++  java
  • 网络流_spfa最小费用最大流

    最大流:

      不断搜索增广路,寻找最小的容量-流量,得到最大流量,但最大流量在有花费时不一定是最小花费。

    最小费用最大流

    算法思想:

      采用贪心的思想,每次找到一条从源点到达汇点的花费最小的路径,增加流量,直到无法找到一条从源点到达汇点的路径,算法结束。 

      由于最大流量有限,每执行一次循环流量都会增加,因此该算法肯定会结束,且同时流量也必定会达到网络的最大流量;同时由于每次都是增加的最小的花费,即当前的最小花费是所有到达当前流量flow时的花费最小值,因此最后的总花费最小。

    附上洛谷P3381模板题:

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<queue>
     5 using namespace std;
     6 
     7 const int INF=0x7f7f7f7f;
     8 const int MAXN=100000;
     9 
    10 struct Edge
    11 {
    12     int u,v,w,c,next;//u起点,v终点,w容量,c花费,next下一条边
    13 }E[MAXN];
    14 int node,head[MAXN];
    15 int pre[MAXN],cost[MAXN],vis[MAXN];
    16 int s,t;
    17 int n,m,ans1,ans2;
    18 
    19 void insert(int u,int v,int w,int c)
    20 {
    21     E[++node]=(Edge){u,v,w,c,head[u]};
    22     head[u]=node;
    23     E[++node]=(Edge){v,u,0,-c,head[v]};
    24     head[v]=node;
    25 }
    26 
    27 bool spfa()
    28 {
    29     queue<int> Q;
    30     memset(cost,0x7f,sizeof(cost));
    31     Q.push(s);
    32     cost[s]=0;vis[s]=1;
    33     while(!Q.empty())
    34     {
    35         int q=Q.front();Q.pop();
    36         for(int i=head[q];i;i=E[i].next)
    37             if(E[i].w&&cost[q]+E[i].c<cost[E[i].v])
    38             {
    39                 cost[E[i].v]=cost[q]+E[i].c;
    40                 pre[E[i].v]=i;
    41                 if(!vis[E[i].v])
    42                 {
    43                     Q.push(E[i].v);
    44                     vis[E[i].v]=1;
    45                 }
    46             }
    47         vis[q]=0;
    48     }
    49     return cost[t]!=INF;
    50 }
    51 
    52 void mcf()
    53 {
    54     int minn=INF;
    55     for(int i=pre[t];i;i=pre[E[i].u])
    56         minn=min(minn,E[i].w);
    57     for(int i=pre[t];i;i=pre[E[i].u])
    58     {
    59         ans2+=minn*E[i].c;
    60         E[i].w-=minn;
    61         E[i^1].w+=minn;
    62     }
    63     ans1+=minn;
    64 }
    65 
    66 int main()
    67 {
    68     scanf("%d%d%d%d",&n,&m,&s,&t);
    69     for(int i=1;i<=m;i++)
    70     {
    71         int u,v,w,c;
    72         scanf("%d%d%d%d",&u,&v,&w,&c);
    73         insert(u,v,w,c);
    74     }
    75     while(spfa()) mcf();
    76     printf("%d %d",ans1,ans2);//ans1最大流 ans2最小费用
    77     return 0;
    78 }
  • 相关阅读:
    python模块添加
    Python 的列表排序
    python中文处理问题
    排序算法堆排序
    搜索二分搜索
    排序算法(随机)快速排序(递归)
    排序算法计数排序
    OO设计原则总结
    异常控制以及进程调度
    ubuntu12.04 alternate win7 双系统安装
  • 原文地址:https://www.cnblogs.com/InWILL/p/9622571.html
Copyright © 2011-2022 走看看