• hdu 6118(最小费用流)


    度度熊的交易计划

    Time Limit: 12000/6000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 871    Accepted Submission(s): 326

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

    喵哈哈村以及周围的村庄可以看做是一共由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
    Source
    直接建图
    对于每个区域i  s->i->t这样建图(双向边)
    s->i的费用为a 流量为b
    i->t的费用为-c  流量为d
    倘若i j两点有联系的话  流量为INF 费用w
    这样跑一边最小费用最大流 
    在spfa算最短路里面我们需要注意的是 每一次找到一条最短路的时候 dis[t]应该是负数  否则就是亏本  亏本的肯定不能采取
      1 #include<iostream>
      2 #include<cstdio>
      3 #include<algorithm>
      4 #include<cstring>
      5 #include<cstdlib>
      6 #include<string.h>
      7 #include<set>
      8 #include<vector>
      9 #include<queue>
     10 #include<stack>
     11 #include<map>
     12 #include<cmath>
     13 typedef long long ll;
     14 typedef unsigned long long LL;
     15 using namespace std;
     16 const double PI=acos(-1.0);
     17 const double eps=0.0000000001;
     18 const int INF=0x3f3f3f3f;
     19 const int N=10000+100;
     20 int head[N];
     21 int dis[N];
     22 int pre[N];
     23 int vis[N];
     24 int tot;
     25 int m,n;
     26 struct node{
     27     int from,to,next,flow,cost;
     28 }edge[N<<1];
     29 void init(){
     30     memset(head,-1,sizeof(head));
     31     tot=0;
     32 }
     33 void add(int u,int v,int c,int cost){
     34     edge[tot].from=u;
     35     edge[tot].to=v;
     36     edge[tot].flow=c;
     37     edge[tot].cost=cost;
     38     edge[tot].next=head[u];
     39     head[u]=tot++;
     40     edge[tot].from=v;
     41     edge[tot].to=u;
     42     edge[tot].flow=0;
     43     edge[tot].cost=-cost;
     44     edge[tot].next=head[v];
     45     head[v]=tot++;
     46 }
     47 int spfa(int s,int t){
     48     memset(pre,-1,sizeof(pre));
     49     memset(dis,INF,sizeof(dis));
     50     //cout<<dis[s]<<endl;
     51     memset(vis,0,sizeof(vis));
     52     queue<int>q;
     53     dis[s]=0;
     54     vis[s]=1;
     55     q.push(s);
     56     while(!q.empty()){
     57         int x=q.front();
     58         q.pop();
     59         vis[x]=0;
     60         for(int i=head[x];i!=-1;i=edge[i].next){
     61             int v=edge[i].to;
     62             if(edge[i].flow&&dis[v]>dis[x]+edge[i].cost){
     63                 dis[v]=edge[i].cost+dis[x];
     64                 pre[v]=i;
     65                 if(vis[v]==0){
     66                     vis[v]=1;
     67                     q.push(v);
     68                 }
     69 
     70             }
     71         }
     72     }
     73     if(dis[t]>0)return 0;
     74     return 1;
     75 }
     76 int MCMF(int s,int t){
     77     int flow=0;
     78     int cost=0;
     79     while(spfa(s,t)){
     80         int minn=INF;
     81         //cout<<3<<endl;
     82         for(int i=pre[t];i!=-1;i=pre[edge[i].from]){
     83             minn=min(minn,edge[i].flow);
     84         }
     85         for(int i=pre[t];i!=-1;i=pre[edge[i].from]){
     86             edge[i].flow=edge[i].flow-minn;
     87             edge[i^1].flow=edge[i^1].flow+minn;
     88             cost=edge[i].cost*minn+cost;
     89         }
     90         flow=flow+minn;
     91     }
     92     return -cost;
     93 }
     94 int main(){
     95     while(scanf("%d%d",&n,&m)!=EOF){
     96         init();
     97         int s=0;
     98         int t=n+100;
     99         for(int i=1;i<=n;i++){
    100             int a,b,c,d;
    101             scanf("%d%d%d%d",&a,&b,&c,&d);
    102             add(s,i,b,a);
    103             add(i,t,d,-c);
    104         }
    105         for(int i=1;i<=m;i++){
    106             int u,v,w;
    107             scanf("%d%d%d",&u,&v,&w);
    108             if(u==v)continue;
    109             add(u,v,INF,w);
    110             add(v,u,INF,w);
    111         }
    112         cout<<MCMF(s,t)<<endl;
    113     }
    114 }
     
  • 相关阅读:
    重载和重写的定义
    方法的重载与重写有什么区别?
    java: while 和do while区别
    java中的运算符
    java 8种基本数据类型
    java.面向对象特征
    java语言的特点
    java.注释类型
    char 和 varchar2 区别
    使用sql对数据库进行简单的增删改查
  • 原文地址:https://www.cnblogs.com/Aa1039510121/p/7360554.html
Copyright © 2020-2023  润新知