最小费用最大流

EK+spfa

其实我也不知道这个算法叫啥,感觉有点像EK

#include<iostream>
#include<queue>
#include<algorithm>
using namespace std;
const int maxn = 5000 + 10;
const int maxm = 50000 + 10;
const int inf = 0x7fffffff;
struct Edge{
    int to, w,dist, next;   //可将花费看成距离
};
Edge e[maxm * 2];
int head[maxn];      //用于静态链表
int dist[maxn];      //距离
int inq[maxn];       //是否在队列中
int flow[maxn];   
int pre[maxn];
int nume[maxn];      //记录边的编号,还可以求反边
int cnt;
int n, m,s,t,maxflow=0;
long long mincost=0;
void init(){
    for (int i = 0; i <= n; i++) head[i] = -1;
    s = 1; t = n;
    cnt = 0;
}
void addedge(int u, int v, int w,int dist){
    e[cnt].to = v; e[cnt].w = w; e[cnt].dist = dist;
    e[cnt].next = head[u]; head[u]= cnt++;
}
int spfa(){   
    queue<int> q;
    for (int i = 0; i <= n; i++) { dist[i] = inf; inq[i] = 0; }
    dist[s] = 0;  flow[s] = inf;
    q.push(s); inq[s] = 1;

    while (!q.empty()){
        int p = q.front(); q.pop();inq[p] = 0;

        for (int i = head[p]; ~i; i = e[i].next){
            int v = e[i].to;
            if (e[i].w > 0 && dist[v] > dist[p] + e[i].dist){
                dist[v] = dist[p] + e[i].dist;            //更新最短路(花费的角度)
                pre[v] = p;                               //记录路径
                nume[v] = i;                              //记录这个顶点的编号,i^1就是反向边
                flow[v] = min(flow[p],e[i].w);            //更新可行流
                if (!inq[v]){ q.push(v); inq[v] = 1; }
            }

        }
    }
    return dist[t] < inf;
}
void MCMF(){   //mcmf主体
    
    while (spfa()){     //如果不可增广,算法结束
        int p = t;
        while (p != s){
            e[nume[p]].w -= flow[t];
            e[nume[p]^1].w += flow[t];
            p = pre[p];
        }
        maxflow += flow[t];
        mincost += 1ll*flow[t] * dist[t];
    }
}
int main()
{
    cin >> n >> m ;
    int a, b, c, d;
    init();
    for (int i = 0; i < m; i++){
        cin >> a >> b >> c >> d;
        addedge(a, b, c, d);
        addedge(b, a, 0, -d);
    }
    MCMF();
    cout << maxflow << ' ' << mincost << endl;
    return 0;
}
View Code

 

posted @ 2019-03-03 11:30  looeyWei  阅读(125)  评论(0)    收藏  举报