HDU6118(费用流水题)

来源:互联网 发布:gta5捏脸数据女韩国 编辑:程序博客网 时间:2024/06/08 02:02

题面
题意就是有n个点,每个点可以生产和销售商品,产量和销量有限制,生产商品有代价,销售有收益。
这n个点还构成一个图,商店可以在图上流,而且是单位流量有费用。
作为一个图论只会网络流的选手,这题就是显然的费用流了。
源向每个点连边,容量为生产的最大值,费用为生产的费用
每个点向汇连边,容量为销量的最大值,费用为负的价格
然后再把图上的边连好,容量为oo,费用为长度
用连续最短路算法,不断寻找最短的增广路,直至增广路费用>0。

我考试时写的丑陋代码

#include<cstdio>#include<algorithm>#include<cmath>#include<cstring>#include<iostream>#include<queue>using namespace std;#define mmst(a, b) memset(a, b, sizeof(a))#define mmcp(a, b) memcpy(a, b, sizeof(b))const int nn=510,N=550,M=20020,oo=1e9,T=501;int n,m,cnt=2;int q[N],head[N],id[N],pre[N],flow[N],d[N];int to[M],cap[M],cost[M],nex[M];bool vis[N];void add(int u,int v,int ca,int co){    to[cnt]=v;    cap[cnt]=ca;    cost[cnt]=co;    nex[cnt]=head[u];    head[u]=cnt++;    to[cnt]=u;    cap[cnt]=0;    cost[cnt]=-co;    nex[cnt]=head[v];    head[v]=cnt++;}bool spfa(int s,int t){    for(int i=1;i<=T;i++)    d[i]=oo;    memset(vis,0,sizeof(vis));    d[s]=0;    flow[s]=oo;    int sum=0,tou=0,tail=0;    q[0]=s;    for(;tou<=tail;)    {        int hy=q[tou%nn];        tou++;        vis[hy]=0;        for(int h=head[hy];h;h=nex[h])        if(d[hy]+cost[h]<d[to[h]]&&cap[h])        {            d[to[h]]=d[hy]+cost[h];            flow[to[h]]=min(flow[hy],cap[h]);            id[to[h]]=h;            pre[to[h]]=hy;            if(!vis[to[h]])            {                vis[to[h]]=1;                tail++;                q[tail%nn]=to[h];                if(d[q[tail%nn]]<d[q[tou%nn]])                swap(q[tail%nn],q[tou%nn]);            }        }    }    return d[t]<oo;}int main(){    while(scanf("%d%d",&n,&m)!=EOF)    {    mmst(head,0);    cnt=2;    for(int i=1;i<=n;i++)    {        int a,b,c,d;        scanf("%d%d%d%d",&a,&b,&c,&d);        add(0,i,b,a);        add(i,T,d,-c);    }    for(int i=1;i<=m;i++)    {        int u,v,k;        scanf("%d%d%d",&u,&v,&k);        if(u!=v)        {            add(u,v,oo,k);            add(v,u,oo,k);        }    }    int ans=0;    for(;spfa(0,T);)    {        if(d[T]>=0)        break;        ans+=d[T]*flow[T];        for(int i=T;i!=0;i=pre[i])        {            cap[id[i]]-=flow[T];            cap[id[i]^1]+=flow[T];        }    }    printf("%d\n",-ans);    }    return 0;}
原创粉丝点击