zoukankan      html  css  js  c++  java
  • (最小费用流)hdu 6118(2017百度之星初赛B 1005) 度度熊的交易计划

    度度熊的交易计划

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


    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

    UPD:

    智障了,请无视掉下述话吧,cost和cap题目中给的acd就是……就是完完全全的费用流裸题。

    恰当的建图之后就是个裸的最小费用流(当然,由于求的是最大盈利,值乘-1进行计算)了。将每个点拆成3个,分别为: 由源点连向的点(边cost=a[i],cap=b[i]) 由第一种点(对应原图中下标设为i)连向的“入点”(对应原图中下标设为j)(cost=-(c[j]-dis[i][j]),cap=a[i])(其中dis[i][j]为i到j的最短路,事先需要floyd跑一边求一下) 由于每个点出售的数量是有限制的,故第三种点为第二种点一一对应连接的(cost=0,cap=d[i])第三种点再连向汇点。

    不过需要注意的是,这样建的图并不一定是满流(因为有的地方可以不生产),故为了保证最小费用流中的满流条件,再增加一个“超级源点”、“超级汇点”,分别与原本的源点、汇点相连,并增加一条从原本的源点连向汇点的cost=0,cap=INF的边。

    建完图之后直接进行最小费用流即可。

      1 #include <cstdio>
      2 #include <iostream>
      3 #include <algorithm>
      4 #include <vector>
      5 #include <set>
      6 #include <map>
      7 #include <string>
      8 #include <cstring>
      9 #include <stack>
     10 #include <queue>
     11 #include <cmath>
     12 #include <ctime>
     13 #include<bitset>
     14 #include <utility>
     15 using namespace std;
     16 #define REP(I,N) for (I=0;I<N;I++)
     17 #define rREP(I,N) for (I=N-1;I>=0;I--)
     18 #define rep(I,S,N) for (I=S;I<N;I++)
     19 #define rrep(I,S,N) for (I=N-1;I>=S;I--)
     20 #define FOR(I,S,N) for (I=S;I<=N;I++)
     21 #define rFOR(I,S,N) for (I=N;I>=S;I--)
     22 #define rank rankk
     23 #define DFT FFT
     24 typedef unsigned long long ull;
     25 typedef long long ll;
     26 //const int INF=0x3f3f3f3f;
     27 const ll INFF=0x3f3f3f3f3f3f3f3fll;
     28 //const ll M=1e9+7;
     29 const ll maxn=2e5+7;
     30 //const int MAXN=1005;
     31 const int MAX=1e6+5;
     32 const int MAX_N=MAX;
     33 //const int N=55;
     34 const ll MOD=1e9+7;
     35 //const double eps=0.00000001;
     36 int gcd(int a,int b){return b?gcd(b,a%b):a;}
     37 template<typename T>inline T abs(T a) {return a>0?a:-a;}
     38 inline ll powMM(ll a,ll b,ll M){
     39     ll ret=1;
     40     a%=M;
     41 //    b%=M;
     42     while (b){
     43         if (b&1) ret=ret*a%M;
     44         b>>=1;
     45         a=a*a%M;
     46     }
     47     return ret;
     48 }
     49 void open()
     50 {
     51     freopen("t.txt","r",stdin);
     52     freopen("out.txt","w",stdout);
     53 }
     54 
     55 const int MAXN = 10000;
     56 const int MAXM = 1000000;
     57 const int INF = 0x3f3f3f3f;
     58 struct Edge
     59 {
     60 int to,next,cap,flow,cost;
     61 }edge[MAXM];
     62 int head[MAXN],tol;
     63 int pre[MAXN],dis[MAXN];
     64 bool vis[MAXN];
     65 int N;//节点总个数,节点编号从0~N-1
     66 void init(int n)
     67 {
     68 N = n;
     69 tol = 0;
     70 memset(head,-1,sizeof(head));
     71 }
     72 void addedge(int u,int v,int cap,int cost)
     73 {
     74 edge[tol].to = v; edge[tol].cap = cap; edge[tol].cost = cost; edge[tol].flow = 0; edge[tol].next = head[u]; head[u] = tol++; edge[tol].to = u; edge[tol].cap = 0; edge[tol].cost = -cost; edge[tol].flow = 0; edge[tol].next = head[v]; head[v] = tol++;
     75 }
     76 bool spfa(int s,int t)
     77 {
     78 queue<int>q;
     79 for(int i = 0;i < N;i++)
     80 {
     81 dis[i] = INF; vis[i] = false; pre[i] = -1;
     82 }
     83 dis[s] = 0; vis[s] = true; q.push(s); while(!q.empty())
     84 {
     85 int u = q.front(); q.pop();
     86 vis[u] = false;
     87 for(int i = head[u]; i != -1;i = edge[i].next)
     88 {
     89 int v = edge[i].to;
     90 
     91 
     92 if(edge[i].cap > edge[i].flow && dis[v] > dis[u] + edge[i].cost )
     93 {
     94 dis[v] = dis[u] + edge[i].cost; pre[v] = i;
     95 if(!vis[v])
     96 {
     97 vis[v] = true; q.push(v);
     98 }
     99 }
    100 }
    101 }
    102 if(pre[t] == -1)return false; else return true;
    103 }
    104 //返回的是最大流,cost存的是最小费用
    105 int minCostMaxflow(int s,int t,int &cost)
    106 {
    107 int flow = 0; cost = 0; while(spfa(s,t))
    108 {
    109 int Min = INF;
    110 for(int i = pre[t];i != -1;i = pre[edge[i^1].to])
    111 {
    112 if(Min > edge[i].cap - edge[i].flow) Min = edge[i].cap - edge[i].flow;
    113 }
    114 for(int i = pre[t];i != -1;i = pre[edge[i^1].to])
    115 {
    116 edge[i].flow += Min; edge[i^1].flow -= Min;
    117 cost += edge[i].cost * Min;
    118 }
    119 flow += Min;
    120 }
    121 return flow;
    122 }
    123 int n,m;
    124 int diss[505][505];
    125 int a[505],b[505],c[505],d[505];
    126 int V;//顶点数
    127 void warshall_floyd()
    128 {
    129     for(int k=1;k<=V;k++)
    130         for(int i=1;i<=V;i++)
    131             for(int j=1;j<=V;j++)
    132                 diss[i][j]=min(diss[i][j],diss[i][k]+diss[k][j]);
    133 }
    134 int main()
    135 {
    136     while(~scanf("%d%d",&n,&m))
    137     {
    138         memset(diss,-1,sizeof(diss));
    139         for(int i=1;i<=n;i++)
    140             scanf("%d%d%d%d",&a[i],&b[i],&c[i],&d[i]);
    141         for(int i=1;i<=n;i++)
    142             for(int j=1;j<=n;j++)
    143                 diss[i][j]=(int)1e9;
    144         for(int i=1;i<=n;i++)
    145             diss[i][i]=0;
    146         for(int i=1;i<=m;i++)
    147         {
    148             int x,y,z;
    149             scanf("%d%d%d",&x,&y,&z);
    150             if(x==y)
    151                 continue;
    152             diss[x][y]=diss[y][x]=min(z,diss[x][y]);
    153         }
    154         V=n;
    155         warshall_floyd();
    156         init(3*n+4);
    157         for(int i=1;i<=n;i++)
    158             addedge(0,i,b[i],a[i]);
    159         for(int i=1;i<=n;i++)
    160         {
    161             for(int j=1;j<=n;j++)
    162             {
    163                 if(diss[i][j]!=-1&&c[j]>=a[i]+diss[i][j])
    164                     addedge(i,j+n,b[i],-(c[j]-diss[i][j]));
    165             }
    166         }
    167         for(int i=1;i<=n;i++)
    168             addedge(i+n,i+2*n,d[i],0);
    169         for(int i=1;i<=n;i++)
    170             addedge(i+2*n,3*n+1,d[i],0);
    171         addedge(3*n+2,0,INF,0);
    172         addedge(3*n+1,3*n+3,INF,0);
    173         addedge(0,3*n+1,INF,0);
    174         int co;
    175         int an=minCostMaxflow(3*n+2,3*n+3,co);
    176         printf("%d
    ",-co);
    177     }
    178 }
  • 相关阅读:
    package.json 笔记
    TypeScript 笔记
    RxJS 笔记
    angular 使用Redux
    ngrx 笔记
    Node 的使用
    imoocLinux环境变量配置文件笔记
    imooc正则表达式学习笔记
    js定时器和linux命令locate
    linux修改PATH环境
  • 原文地址:https://www.cnblogs.com/quintessence/p/7354526.html
Copyright © 2011-2022 走看看