zoukankan      html  css  js  c++  java
  • 费用流

    最小费用最大流(转至Lost(转至威士忌)的代码)

    )):

    每次在s-t之间找出费用最小的一条路径即单源最短路,如果t点不再被访问到,则算法终止。否则,按着最短路径找出最小剩余容量c,最大流量加上 c,再更新最短路径上的边,前向弧减去c,反向弧加上c,并且造一条逆向的费用边,最小费用加上每条边的花销,每条边的花销=单位费用*c。

    最小费用最大流既能求最小费用,又能得出最大流,是更为一般的模型。

    牛人哈~~~自己也懒得看原理了,代码中使用了bellman-ford算法,貌似可以改进为spfa,会更好。

    代码
    /**** **** **** **** **** ****
    网络中最小费用最大流
    参数含义: n代表网络中的总节点数
    net[][]代表剩余网络
    cost[][]代表单位费用
    path[]保存增广路径
    ecost[]源点到各点的最短路
    算法:初始最小费用和最大流均为,寻找单位费用最短路
    在最短路中求出最大流,即为增广路,再修改剩余网络,直到无可增广路为止
    返回值: 最小费用,最大流量
    **** **** **** **** **** ***
    */
    const int NMAX = 210;
    int net[NMAX][NMAX], cost[NMAX][NMAX];
    int path[NMAX], ecost[NMAX];
    int n;
    bool bellman_ford()
    {
    int i,j;
    memset(path,
    -1,sizeof(path));
    fill(ecost, ecost
    +NMAX, INT_MAX);
    ecost[
    0] = 0;

    bool flag = true;
    while(flag) {
    flag
    = false;
    for(i=0;i<=n;i++) {
    if(ecost[i] == INT_MAX) {
    continue ;
    }
    for(j=0;j<=n;j++) {
    if(net[i][j] > 0 && ecost[i]+cost[i][j] < ecost[j]) {
    flag
    = true;
    ecost[j]
    = ecost[i]+cost[i][j];
    path[j]
    = i;
    }
    }
    }
    }
    return ecost[n] != INT_MAX;
    }

    int min_cost_max_flow()
    {
    int i,j;
    int mincost = 0, maxflow = 0;
    while( bellman_ford() ) {
    int now = n;
    int neck = INT_MAX;
    while(now != 0) {
    int pre = path[now];
    neck
    = min(neck, net[pre][now]);
    now
    = pre;
    }
    maxflow
    += neck;
    now
    = n;
    while(now != 0) {
    int pre = path[now];
    net[pre][now]
    -= neck;
    net[now][pre]
    += neck;
    cost[now][pre]
    = - cost[pre][now];
    mincost
    += cost[pre][now] * neck;
    now
    = pre;
    }
    }
    return mincost;
    }

    spfa+静态邻接表

    代码
    /*存边的时候注意前向弧存在Edge数组的偶数里面,后向弧存在奇数里面,并且相差1*/

    #include
    <iostream>
    #include
    <queue>
    using namespace std;

    #define fmax(a,b) (a>b?a:b)
    #define fmin(a,b) (a<b?a:b)
    const long inf = 1e9;
    const long maxn_edge = 10005;
    const long maxn_point = 105;

    int Index;
    int n,m;
    struct node
    {
    int to;
    int c; //容量
    int w; //费用
    int next;
    }Edge[maxn_edge];
    int pre[maxn_point];
    int dir[maxn_point],path_v[maxn_point],path_e[maxn_point],vis[maxn_point];//求最短路
    queue<int> Q;

    inline
    void _insert(int from,int to,int c,int w)
    {
    Edge[Index].to
    = to;
    Edge[Index].c
    = c;
    Edge[Index].w
    = w;
    Edge[Index].next
    = pre[from];
    pre[from]
    = Index++;
    }

    void insert(int from,int to,int c,int w)
    {
    _insert(from,to,c,w);
    _insert(to,from,
    0,-w);
    }

    int Init()
    {
    //CODE
    return 1;
    }
    int min_cost_max_flow(int start,int end)
    {
    int i;
    int min_cost = 0,max_flow = 0;
    while(true)
    {
    memset(path_v,
    -1,sizeof(path_v));
    memset(path_e,
    -1,sizeof(path_e));
    memset(vis,
    0,sizeof(vis));
    fill(dir,dir
    +maxn_point,inf);

    dir[start]
    = 0;
    Q.push(start);
    vis[start]
    = true;
    while(!Q.empty())
    {
    int x = Q.front();
    vis[x]
    = false;
    Q.pop();

    for(i=pre[x];(i+1);i=Edge[i].next)
    {
    int y = Edge[i].to;
    if(Edge[i].c && dir[y] > dir[x] + Edge[i].w)
    {
    dir[y]
    = dir[x] + Edge[i].w;
    if(!vis[y])
    {
    vis[y]
    = true;
    Q.push(y);
    }
    path_v[y]
    = x,path_e[y] = i;
    }
    }
    }


    if(path_v[end] == -1) //dir[end] == inf
    break;

    int Min = inf;
    for(i=end;i!=start;i=path_v[i])
    {
    Min
    = fmin(Min,Edge[path_e[i]].c);
    }

    max_flow
    += Min;
    min_cost
    += Min * dir[end];

    for(i=end;i!=start;i=path_v[i])
    {
    Edge[path_e[i]].c
    -= Min;
    Edge[path_e[i]
    ^1].c += Min;
    }
    }

    return min_cost;
    }

    int main()
    {
    while(Init())
    {
    int num = min_cost_max_flow(1,n);
    printf(
    "%d\n",num);
    }
    return 0;
    }

  • 相关阅读:
    hbase Compaction
    hadoop集群 动态添加或删除节点
    Hadoop节点迁移
    Spark程序运行常见错误解决方法以及优化
    用python执行sql来验证数据是否准时导入了目标库
    kylin2.3版本启用jdbc数据源(可以直接通过sql生成hive表,省去手动导数据到hive,并建hive表的麻烦)
    phoenix 二级索引使用实践
    jenkins任务失败,发送邮件通知
    Coolite学习
    MySql连接和授权命令
  • 原文地址:https://www.cnblogs.com/silencExplode/p/1939908.html
Copyright © 2011-2022 走看看