hdu6118 最小费用最大流

来源:互联网 发布:城市网络超市 编辑:程序博客网 时间:2024/06/07 05:29

传送门
汉语题,不解释;
建图方式:建立超级源点S,超级汇点T,S指向所有点i,边的流量为i点的出货量,费用为成本,所有点i指向汇点T,流量为进货量,费用为 -收货价格,那么求一条以费用为权值的最短路时,最短路长度越小,收益会越大,因为负的就是赚的钱。
样例图片示意图
样例示意图
了解了建图,套套模板就过了啊,注意一点就是最短路小于0是才跑流量,大于等于0时结束。

#include <bits/stdc++.h >using namespace std;typedef long long LL;const int MAXN = 1e5+5;using namespace std;const int INF=0x3f3f3f3f;struct Edge{    int to,next,flow,cap,cost;} edge[MAXN*4];int tot,head[MAXN];int pre[MAXN],dis[MAXN];bool vis[MAXN];int N;void init(int n){    N=n;    memset(head,-1,sizeof(head));    tot=0;}void add(int u,int v,int cap,int cost){    edge[tot].to=v;    edge[tot].cap=cap;    edge[tot].flow=0;    edge[tot].cost=cost;    edge[tot].next=head[u];    head[u]=tot++;    edge[tot].to=u;    edge[tot].cap=0;    edge[tot].flow=0;    edge[tot].cost=-cost;    edge[tot].next=head[v];    head[v]=tot++;}bool spfa(int s,int t){    queue<int>Q;    for(int i=0; i<N; i++)    {        dis[i]=INF;        vis[i]=false;        pre[i]=-1;    }    dis[s]=0;    vis[s]=true;    Q.push(s);    while(!Q.empty())    {        int u=Q.front();        Q.pop();        vis[u]=false;        for(int i=head[u]; i!=-1; i=edge[i].next)        {            int v=edge[i].to;            if(edge[i].cap>edge[i].flow&&dis[v]>dis[u]+edge[i].cost)            {                dis[v]=dis[u]+edge[i].cost;                pre[v]=i;                if(!vis[v])                {                    vis[v]=true;                    Q.push(v);                }            }        }    }    if(pre[t]==-1)        return false;    return true;}int minCostMaxflow(int s,int t){    int ans=0;    while(spfa(s,t))    {        int Min=INF;        for(int i=pre[t]; i!=-1; i=pre[edge[i^1].to])            if(Min>edge[i].cap-edge[i].flow)                Min=edge[i].cap-edge[i].flow;        for(int i=pre[t]; i!=-1; i=pre[edge[i^1].to])        {            edge[i].flow+=Min;            edge[i^1].flow-=Min;        }        if(dis[t] > 0)            return ans;        ans += dis[t]*Min;///Min是流量,dis[t]是费用,相乘得到理由    }    return ans;}int main(){    int n,m;    while(scanf("%d%d",&n,&m)!=EOF)    {        int S=0,T=n+1;        init(T+1);        int a,b,c,d;        for(int i=1; i<=n; i++)        {            scanf("%d%d%d%d",&a,&b,&c,&d);            add(S,i,b,a);            add(i,T,d,-c);        }        for(int i=1; i<=m; i++)        {            scanf("%d%d%d",&a,&b,&c);            add(a,b,INF,c);            add(b,a,INF,c);        }        printf("%d\n",-minCostMaxflow(S,T));    }    return 0;}
原创粉丝点击