最小费用最大流

来源:互联网 发布:淘宝上哪些店银是真的 编辑:程序博客网 时间:2024/04/29 06:11
#include<stdio.h>#include<stdlib.h>#include<string.h>#include<algorithm>#include<queue>using namespace std;const int maxn=1e9;int src,sink,n,m,e,head[1005],pnt[50000],next[50000],cost[50000],cnt[1005],pre[1005],dis[1005],flow[50000];bool vis[1005];int addedge(int u,int v,int c,int f){    pnt[e]=v;    cost[e]=c;    flow[e]=f;    next[e]=head[u];    head[u]=e++;    pnt[e]=u;    cost[e]=-c;    flow[e]=0;    next[e]=head[v];    head[v]=e++;}bool spfa(int s,int t){    queue<int>q;    memset(vis,0,sizeof(vis));    memset(cnt,0,sizeof(cnt));    memset(pre,-1,sizeof(pre));    for(int i=0; i<=n+1; i++)    {        dis[i]=maxn;    }    vis[s]=1;    dis[s]=0;    q.push(s);    while(!q.empty())    {        int u=q.front();        q.pop();        vis[u]=0;        for(int i=head[u]; ~i; i=next[i])        {            int v=pnt[i];            if(dis[v]>dis[u]+cost[i]&&flow[i])            {                dis[v]=dis[u]+cost[i];                pre[v]=i;                if(!vis[v])                {                    vis[v]=1;                    q.push(v);                    if(++cnt[v]==n)                        return false;                }            }        }    }    return dis[t]!=maxn;}int mincostflow(int s,int t){    int ans=0;    while(spfa(s,t))    {        int mini=maxn;        for(int i=pre[t]; ~i; i=pre[pnt[i^1]])        {            mini=min(mini,flow[i]);        }        for(int i=pre[t]; ~i; i=pre[pnt[i^1]])        {            flow[i]-=mini;            flow[i^1]+=mini;        }        ans+=mini*dis[t];    }    return ans;}int main(){    while(~scanf("%d%d",&n,&m))    {        src=0;        sink=n+1;        e=0;        memset(head,-1,sizeof(head));        for(int i=1; i<=m; i++)        {            int f,t,v;            scanf("%d%d%d",&f,&t,&v);            addedge(f,t,v,1);            addedge(t,f,v,1);        }        addedge(src,1,0,2);        addedge(n,sink,0,2);        printf("%d\n",mincostflow(src,sink));    }    return 0;}

0 0