Live2d Test Env

HDU6118:度度熊的交易计划(入门级最小费用可行流)

度度熊参与了喵哈哈村的商业大会,但是这次商业大会遇到了一个难题: 

喵哈哈村以及周围的村庄可以看做是一共由n个片区,m条公路组成的地区。 

由于生产能力的区别,第i个片区能够花费a[i]元生产1个商品,但是最多生产b[i]个。 

同样的,由于每个片区的购买能力的区别,第i个片区也能够以c[i]的价格出售最多d[i]个物品。 

由于这些因素,度度熊觉得只有合理的调动物品,才能获得最大的利益。 

据测算,每一个商品运输1公里,将会花费1元。 

那么喵哈哈村最多能够实现多少盈利呢? 

Input本题包含若干组测试数据。 
每组测试数据包含: 
第一行两个整数n,m表示喵哈哈村由n个片区、m条街道。 
接下来n行,每行四个整数a[i],b[i],c[i],d[i]表示的第i个地区,能够以a[i]的价格生产,最多生产b[i]个,以c[i]的价格出售,最多出售d[i]个。 
接下来m行,每行三个整数,u[i],v[i],k[i],表示该条公路连接u[i],v[i]两个片区,距离为k[i] 

可能存在重边,也可能存在自环。 

满足: 
1<=n<=500, 
1<=m<=1000, 
1<=a[i],b[i],c[i],d[i],k[i]<=1000, 
1<=u[i],v[i]<=n 
Output输出最多能赚多少钱。 
Sample Input

2 1
5 5 6 1
3 5 7 7
1 2 1

Sample Output

23

思路:建图,每次spfa完,如果dis[S]<0,说明有收益,累加即可,否则退出。

#include<bits/stdc++.h>
const int inf=1<<30;
const int maxn=1010;
using namespace std;
int To[maxn*6],Laxt[maxn],Next[maxn*6],cap[maxn*6],cost[maxn*6];
int S,T,cnt=1,dis[maxn],ans;
bool inq[maxn],vis[maxn];
deque<int>q;
void add(int u,int v,int c,int cc)
{ 
    Next[++cnt]=Laxt[u];Laxt[u]=cnt;
    To[cnt]=v;cap[cnt]=c;cost[cnt]=cc; 
}
bool spfa()
{
    for(int i=0;i<=T;i++) inq[i]=0;
    for(int i=0;i<=T;i++) dis[i]=inf;
    inq[T]=1; dis[T]=0; q.push_back(T);
    while(!q.empty())
    {    
        int u=q.front(); q.pop_front();
        inq[u]=0;
        for(int i=Laxt[u];i;i=Next[i])
        {
            int v=To[i];
            if(cap[i^1]&&dis[v]>dis[u]-cost[i])
            {
                dis[v]=dis[u]-cost[i];
                if(!inq[u]){
                    inq[v]=1;
                    if(q.empty()||dis[v]>dis[q.front()]) q.push_back(v);
                    else q.push_front(v);
                }
            }
        }
    }
    return dis[S]<inf;
}
int dfs(int u,int flow)
{
    vis[u]=1;
    if(u==T||flow==0) return flow;
    int tmp,delta=0;
    for(int i=Laxt[u];i;i=Next[i])
    {
        int v=To[i];
        if((!vis[v])&&cap[i]&&dis[v]==dis[u]-cost[i])
        {
            tmp=dfs(v,min(cap[i],flow-delta));
            delta+=tmp; cap[i]-=tmp; cap[i^1]+=tmp;
        }
    }
    return delta;
}
int main()
{
    int N,M,a,b,c,d,u,v,w,i;
    while(~scanf("%d%d",&N,&M)){
        S=0; T=N+1; cnt=1; ans=0;
        for(i=0;i<=T;i++) Laxt[i]=0;
        for(i=1;i<=N;i++){
            scanf("%d%d%d%d",&a,&b,&c,&d);
            add(S,i,b,a); add(i,S,0,-a);
            add(i,T,d,-c); add(T,i,0,c); 
        }
        for(i=1;i<=M;i++){
            scanf("%d%d%d",&u,&v,&w);
            add(u,v,inf,w); add(v,u,0,-w);
            add(v,u,inf,w); add(u,v,0,-w); 
        }
        while(spfa()){
            if(dis[S]>0) break; vis[T]=1; 
            while(vis[T]){
                for(i=0;i<=T;i++) vis[i]=0;
                ans-=dis[S]*dfs(S,inf);
            }
        }
        printf("%d\n",ans);
    }
    return 0;
}

 

posted @ 2018-07-31 20:59  nimphy  阅读(290)  评论(0编辑  收藏  举报