2017"百度之星"程序设计大赛

来源:互联网 发布:mysql进程意外终止 编辑:程序博客网 时间:2024/06/08 11:52

度度熊的交易计划

 
 Accepts: 460
 
 Submissions: 2329
 Time Limit: 12000/6000 MS (Java/Others)
 
 Memory Limit: 32768/32768 K (Java/Others)
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 15 5 6 13 5 7 71 2 1
Sample Output
23

思路:


很裸的一个最小费用流的问题.


我们建图:

①建立源点,连入各个节点,花费为-c【i】,流为d【i】。

②建立汇点,将各个节点连入汇点,花费为a【i】,流为b【i】。

③将图的边(u,v)加到网络中,花费为w,流为INF。


然后连续最短路跑费用流就行了,值得注意的一个坑点是,我们如果从源点到汇点的距离大于0的时候,我们这条边如果走过去了就相当于赔钱了。

所以当dis【tt】>0的时候,我们终止跑费用流。


Ac代码:

#include<bits/stdc++.h>using namespace std;struct node{    int from;    int to;    int w;    int f;    int num;    int next;}e[2000000];int dist[505][505];int head[10000];int vis[10000];int dis[10000];int pre[10000];int path[10000];int n,m,kk,cont,ss,tt;void add(int from,int to,int f,int w){    e[cont].to=to;    e[cont].f=f;    e[cont].w=w;    e[cont].num=cont;    e[cont].next=head[from];    head[from]=cont++;}int SPFA(){    for(int i=1;i<=tt;i++)dis[i]=0x3f3f3f3f;    dis[ss]=0;    memset(vis,0,sizeof(vis));    queue<int >s;    s.push(ss);    while(!s.empty())    {        int u=s.front();        s.pop();        vis[u]=0;        for(int i=head[u];i!=-1;i=e[i].next)        {            int v=e[i].to;            int w=e[i].w;            int f=e[i].f;            if(f&&dis[v]>dis[u]+w)            {                dis[v]=dis[u]+w;                pre[v]=u;                path[v]=e[i].num;                if(vis[v]==0)                {                    vis[v]=1;                    s.push(v);                }            }        }    }    if(dis[tt]>0)return 0;    else return 1;}void MCMF(){    int ans=0;    int maxflow=0;    while(SPFA()==1)    {        int minn=0x3f3f3f3f;        for(int i=tt;i!=ss;i=pre[i])        {            minn=min(e[path[i]].f,minn);        }        for(int i=tt;i!=ss;i=pre[i])        {            e[path[i]].f-=minn;            e[path[i]^1].f+=minn;        }        ans+=minn*dis[tt];        maxflow+=minn;    }    printf("%d\n",-ans);}int main(){    int n,m;    while(~scanf("%d%d",&n,&m))    {        ss=n+1;        tt=ss+1;        cont=0;        memset(head,-1,sizeof(head));        for(int i=1;i<=n;i++)        {            for(int j=1;j<=n;j++)            {                dist[i][j]=0x3f3f3f3f;            }            dist[i][i]=0;        }        for(int i=1;i<=n;i++)        {            int aa,bb,cc,dd;            scanf("%d%d%d%d",&aa,&bb,&cc,&dd);            add(ss,i,dd,-cc);            add(i,ss,0,cc);            add(i,tt,bb,aa);            add(tt,i,0,-aa);        }        for(int i=1;i<=m;i++)        {            int x,y,w;            scanf("%d%d%d",&x,&y,&w);            dist[x][y]=min(dist[x][y],w);            dist[y][x]=min(dist[y][x],w);        }        for(int i=1;i<=n;i++)        {            for(int j=1;j<=n;j++)            {                if(dist[i][j]==0x3f3f3f3f)continue;                add(i,j,0x3f3f3f3f,dist[i][j]);                add(j,i,0,-dist[i][j]);            }        }        MCMF();    }}














原创粉丝点击