最小费用最大流

用SPFA增广就可以了,(*^▽^*)

附上代码

#include<cstdio>
#include<deque>
#include<cstring>
#define N 10000+10
#define M 50000+10
#define inf 1e9
#define ll long long
using namespace std;
int arnum=1,head[N];
struct arc{int next,to,cost,cap;}ar[M];
void add(int from,int to,int cap,int cost){
    ar[++arnum].next=head[from];
    ar[arnum].to=to;
    ar[arnum].cap=cap;
    ar[arnum].cost=cost;
    head[from]=arnum;    
}
void insert(int from,int to,int cap,int cost){add(from,to,cap,cost);add(to,from,0,-cost);}
int book[N],way[M],dis[N],pre[M];
deque<int>Q;
ll Minflow,Mincost;
bool SPFA(int n)
{
    memset(book,0,sizeof(book));
     memset(way,0,sizeof(way));
     memset(pre,0,sizeof(pre));
    for(int i=1;i<=n;i++)dis[i]=inf;
    Q.clear();
    dis[1]=0,book[1]=1;
    Q.push_back(1);
    while(!Q.empty())
    {
        int u=Q.front();
        Q.pop_front();
        book[u]=0;
        for(int i=head[u];i;i=ar[i].next)
        {
            int v=ar[i].to;
            int cap=ar[i].cap;
            if(cap>0&&dis[v]>dis[u]+ar[i].cost)
            {
                dis[v]=dis[u]+ar[i].cost;
                way[v]=u;
                pre[v]=i;
                if(!book[v])
                 {
                      book[v]=1; 
                      if(Q.empty()||dis[v]>dis[Q.front()])Q.push_back(v);
                         else Q.push_front(v);
                 }
            }
        }
    }
    if(dis[n]==inf)return false;
    int minn=inf;
    for(int u=n;u!=1;u=way[u])
        minn=min(minn,ar[pre[u]].cap);
    Minflow+=minn;
    Mincost+=minn*dis[n];
    for(int u=n;u!=1;u=way[u])
    {
        ar[pre[u]].cap-=minn;
        ar[pre[u]^1].cap+=minn;
    }
    return true;
}
int main()
{
    int n,m;scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++){
        int a,b,c,d;
        scanf("%d%d%d%d",&a,&b,&c,&d);
        insert(a,b,c,d);
    }
    while(SPFA(n));
    printf("%lld %lld",Minflow,Mincost);
    return 0;
}

 

posted @ 2017-10-06 17:07  star_eternal  阅读(163)  评论(0编辑  收藏  举报