• 网络流最小费用最大流


    最小费用最大流

    题目描述

    如题,给出一个网络图,以及其源点和汇点,每条边已知其最大流量和单位流量费用,求出其网络最大流和在最大流情况下的最小费用。

    输入格式

    第一行包含四个正整数N、M、S、T,分别表示点的个数、有向边的个数、源点序号、汇点序号。

    接下来M行每行包含四个正整数ui、vi、wi、fi,表示第i条有向边从ui出发,到达vi,边权为wi(即该边最大流量为wi),单位流量的费用为fi。

    输出格式

    一行,包含两个整数,依次为最大流量和在最大流量情况下的最小费用。

    思路

    求出一条最小费用边,然后对这条边增广,重复上述过程,直到没有到汇点的边流

    求最小费用边,用spfa()

    code

    #include <bits/stdc++.h>
    using namespace std;
    #define mem(a,b) memset(a,b,sizeof(a))
    #define int long long
    const int inf = 0x3f3f3f3f;
    const int maxn = 1000;
    const int M = 1e9+7;
    int n,m,s,t;
    
    struct node
    {
        int to,cost,dis,next;
    }a[2000];           //边数
    
    int head[maxn],cnt = 2;
    
    void ad(int u,int v,int w,int f)
    {
        a[cnt].to = v;a[cnt].cost = w;a[cnt].dis = f;
        a[cnt].next = head[u];head[u] = cnt;cnt++;
    }
    
    void add(int u,int v,int w,int f)       //建图
    {
        ad(u,v,w,f);ad(v,u,0,-f);
    }
    
    int dis[maxn];
    bool vis[maxn];
    
    int pre[maxn];      //前驱
    int incf[maxn];      //当前路上的最小流
    
    bool spfa()
    {
        mem(dis,inf);mem(vis,0);
        dis[s] = 0;incf[s] = inf;
        queue<int> q;q.push(s);
        while(!q.empty())
        {   
            int u = q.front();q.pop();vis[u] = 0;
            for(int i = head[u];i; i = a[i].next)
            {   
                if(!a[i].cost) continue;
                int v = a[i].to;
                if(dis[v] > dis[u]+a[i].dis)
                {
                    dis[v] = dis[u]+a[i].dis;
    
                    incf[v] = min(incf[u],a[i].cost);
                    pre[v] = i;
    
                    if(!vis[v])
                    {
                        vis[v] = 1;
                        q.push(v);
                    }
                }
            }
        }
        if(dis[t] < inf) return 1;
        return 0;
    }
    
    int maxflow,mincost;
    
    vector<int> vt;
    
    void mcff()
    {
        while (spfa())
        {   
            maxflow += incf[t];
            mincost += dis[t]*incf[t];
            vt.push_back(dis[t]*incf[t]);
            int x = t;
            while(x != s)
            {
                int i = pre[x];
                a[i].cost -= incf[t];
                a[i^1].cost += incf[t];
                x = a[i^1].to;
            }
        }
    }
    

    例题

    https://www.luogu.com.cn/problem/P3381

  • 相关阅读:
    KVM 核心功能:磁盘虚拟化
    KVM 核心功能:内存虚拟化
    KVM 核心功能:CPU 虚拟化
    OpenStack 工作流组件: Mistral
    QT 5 种标准对话框使用方法,及实现效果,之二 —— 颜色对话框(QColorDialog)
    Git 安装
    在多人共同开发一个项目中使用 Git 的简单流程
    QT 5 种标准对话框使用方法,及实现效果,之一 —— 文件对话框(QFileDialog)
    Spark安装
    DATAFUN-推荐算法
  • 原文地址:https://www.cnblogs.com/hezongdnf/p/12121301.html
Copyright © 2020-2023  润新知