最小费用最大流(MFMC 邻接表 无向边)

[困]坑点:无向边,每条边只能走一次,但正向走一次后反向还能走一次,所以每次输入要建四条边。

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <queue>
using namespace std;
int n,m,cnt;
int head[50500],vis[50500],pre[50500];
long long dis[50500];
struct edge{
    int u,v,w,cap,next;
}e[50050<<2];
void Initial()
{
    memset(head,-1,sizeof(head));
}
bool SPFA()
{
    memset(pre,-1,sizeof(pre));
    for(int i=0;i<=n+2;i++){
        dis[i]=1e11;
    }
    memset(vis,0,sizeof(vis));
    queue <int>que;
    vis[0]=1;
    que.push(0);
    dis[0]=0;
    while(!que.empty()){
        int d=que.front();
        que.pop();
        vis[d]=0;
        for(int i=head[d];i!=-1;i=e[i].next){
            int v=e[i].v;
            if(dis[v]>dis[d]+e[i].w && e[i].cap){
                dis[v]=dis[d]+e[i].w;
                pre[v]=i;
                if(!vis[v]){
                    vis[v]=1;
                    que.push(v);
                }
            }
        }
    }
    if(dis[n+1]<1e11){
        return true;
    }
    return false;
}
int MCMF()
{
    int flow=0,mincost=0;
    while(SPFA()){
        long long Minflow=1e11;
        int d=n+1;
        for(int i=pre[d];i!=-1;i=pre[e[i].u]){
            Minflow=min(Minflow,(long long)e[i].cap);
        }
        flow+=Minflow;
        for(int i=pre[d];i!=-1;i=pre[e[i].u]){
            e[i].cap-=Minflow;
            e[i^1].cap+=Minflow;
        }
        mincost+=dis[d];
    }
    return mincost;

}
void add(int u,int v, int cap,int w)
{
        e[cnt].u=u;
        e[cnt].v=v;
        e[cnt].w=w;
        e[cnt].cap=cap;
        e[cnt].next=head[e[cnt].u];
        head[u]=cnt++;
        e[cnt].v=u;
        e[cnt].u=v;
        e[cnt].w=-1*w;
        e[cnt].cap=0;
        e[cnt].next=head[e[cnt].u];
        head[v]=cnt++;
}
int main()
{
    while(~scanf("%d%d",&n,&m)){
        cnt=0;
        Initial();
        for(int i=0;i<m;i++){
            int u,v,w;
            scanf("%d%d%d",&u,&v,&w);
            add(u,v,1,w);
            add(v,u,1,w);
        }
        add(0,1,2,0);
        add(n,n+1,2,0);
        int ans=MCMF();
        printf("%d\n",ans);
    }
    return 0;
}
时间: 2024-08-05 11:24:52

最小费用最大流(MFMC 邻接表 无向边)的相关文章

no-understand 最小费用最大流-poj-2135

Farm Tour Description When FJ's friends visit him on the farm, he likes to show them around. His farm comprises N (1 <= N <= 1000) fields numbered 1..N, the first of which contains his house and the Nth of which contains the big barn. A total M (1 &

poj 2135 Farm Tour (最小费用最大流模板)

网络流的费用: 在实际应用中,与网络流有关的问题,不仅涉及流量,而且还有费用的因素.网络的每一条边(v,w)除了给定容量cap(v,w)外,还定义了一个单位流量费用cost(v,w) 最小费用最大流问题 给定网络G,要求G的一个最大用流flow,使流的总费用最小. 求解MCMF问题的算法: 最小费用最大流最常用和基本的算法我们可以称它为最小费用路算法,其思想与求最大流的增广路算法类似,不断在残流网络中寻找从源s到汇t的最小费用路,即残流网络中从s到t的以费用为权的最短路,然后沿最小费用路增流,直

POJ 3422 Kaka&#39;s Matrix Travels 【最小费用最大流】

题意: 卡卡有一个矩阵,从左上角走到右下角,卡卡每次只能向右或者向下.矩阵里边都是不超过1000的正整数,卡卡走过的元素会变成0,问卡卡可以走k次,问卡卡最多能积累多少和. 思路: 最小费用最大流的题目. 建图自己没想出来,看了大神的建边,把每个点分解成两个点,一个代表进入一个代表出去,然后每个进入和每个出去连边,容量是1价值是这个点的矩阵的数值.然后因为可以不进去,所以起点要和别的矩阵元素的起点建边,终点也要和别的矩阵矩阵元素的起点建边,最后跑下最小费用最大流. 这题最右下角的矩阵元素需要特殊

poj 2516 最小费用最大流

Language: Default Minimum Cost Time Limit: 4000MS   Memory Limit: 65536K Total Submissions: 14334   Accepted: 4908 Description Dearboy, a goods victualer, now comes to a big problem, and he needs your help. In his sale area there are N shopkeepers (m

hdoj 3599 最小费用最大流

War Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 1545    Accepted Submission(s): 338 Problem Description In the war between Anihc and Bandzi, Anihc has won Bangzi. At that time, Lvbin, the ki

BZOJ 1061 志愿者招募(最小费用最大流)

题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1061 题意:申奥成功后,布布经过不懈努力,终于 成为奥组委下属公司人力资源部门的主管.布布刚上任就遇到了一个难题:为即将启动的奥运新项目招募一批短期志愿者.经过估算,这个项目需要N 天才能完成,其中第i 天至少需要Ai 个人. 布布通过了解得知,一共有M 类志愿者可以招募.其中第i 类可以从第Si 天工作到第Ti 天,招募费用是每人Ci 元.新官上任三把火,为了出色地完成自己的工作,布

POJ 2195:Going Home(最小费用最大流)

http://poj.org/problem?id=2195 题意:有一个地图里面有N个人和N个家,每走一格的花费是1,问让这N个人分别到这N个家的最小花费是多少. 思路:通过这个题目学了最小费用最大流.最小费用最大流是保证在流量最大的情况下,使得费用最小. 建图是把S->人->家->T这些边弄上形成一个网络,边的容量是1(因为一个人只能和一个家匹配),边的费用是曼哈顿距离,反向边的费用是-cost. 算法的思想大概是通过SPFA找增广路径,并且找的时候费用是可以松弛的.当找到这样一条增

最小费用最大流基础模板(洛谷3381)

如题,给出一个网络图,以及其源点和汇点,每条边已知其最大流量和单位流量费用,求出其网络最大流和在最大流情况下的最小费用. 输入格式: 第一行包含四个正整数N.M.S.T,分别表示点的个数.有向P3381 [模板]最小费用最大流边的个数.源点序号.汇点序号. 接下来M行每行包含四个正整数ui.vi.wi.fi,表示第i条有向边从ui出发,到达vi,边权为wi(即该边最大流量为wi),单位流量的费用为fi. 输出格式: 一行,包含两个整数,依次为最大流量和在最大流量情况下的最小费用. 输入样例#1:

poj_2315 最小费用最大流

题目大意 一个图上有N个顶点,从1到N标号,顶点之间存在一些无向边,边有长度,要求从顶点1走到顶点N,再从顶点N走回顶点1,其中不必要经过每个顶点,但是要求走的路径上的边只能经过一次.求出从1--->N-->1的路径的长度最小值. 题目分析 每条无向边最多只能走一次,可以视为这些边的容量只有1.题目中要求从顶点1走到N再走回顶点1,其中经过的边只能走一次,其实可以看做从顶点1出发的两条不同的路径(路径的边不能有重合)到达顶点N.那么就可以视为,从顶点1出发到达顶点N的总流量为2. 题目要求总路