NOIP 2016 费用流
来源:互联网 发布:双色球数据分据库 编辑:程序博客网 时间:2024/06/06 05:00
飞扬的小鸟
【问题描述】
Flappy Bird是一款风靡一时的休闲手机游戏。玩家需要不断控制点击手机
屏幕的频率来调节小鸟的飞行高度,让小鸟顺利通过画面右方的管道缝隙。如果
小鸟一不小心撞到了水管或者掉在地上的话,便宣告失败。
现在小鸟们遇到了一个难题,他们遇到了一堵巨大的墙,墙上仅有m个洞供
他们通过,由于小鸟们的体型不同且墙上洞的形状也不同,所以每种体型的鸟通
过每个洞的时间都不同,鸟的体型共有n种,第i种体型的鸟通过第j个洞需要的
时间记为T(i,j),且一个洞必须前一只鸟通过之后后一只鸟才能开始通过。
从时刻0开始,鸟开始通过,而每一只鸟的等待时间为从时刻0到自己已经通
过洞的时间。现在知道了第i种体型的鸟有pi只,请求出使所有鸟都通过墙的最
少的等待时间之和。
【输入格式】
第1行包含两个正整数n和m,表示鸟的体型的种数和墙洞的数量。
第2行包含n个正整数,其中第i个数为pi,表示点第i种体型的鸟的只数。
接下来有n行,每行包含m个非负整数,这n行中的第i行的第j个数为t(i,j),
表示第i种体型的鸟通过第j个墙洞所需的时间。输入文件中每行相邻的两个数之
间均由一个空格隔开,行末均没有多余空格。
【输出格式】
输出仅一行包含一个整数,为总等待时间的最小值。
【输入输出样例】
bird.in bird.out3 2
3 1 1
5 7
3 6
8 947
全国信息学奥林匹克联赛(NOIP2016) 复赛模拟 提高组
第 5 页 共5页
【数据范围】
每组数据的n、 m和p值如下:
对于 100%的数据, n<=40,m<=100,p<=800,t(i,j)<=1000(p 为鸟的总只数)
序号 n= m= p=1 5 5 102 40 1 4003 40 2 3004 40 40 405 5 40 1006 10 50 2007 20 60 4008 40 80 6009 40 100 80010 40 100 800
【问题描述】
Flappy Bird是一款风靡一时的休闲手机游戏。玩家需要不断控制点击手机
屏幕的频率来调节小鸟的飞行高度,让小鸟顺利通过画面右方的管道缝隙。如果
小鸟一不小心撞到了水管或者掉在地上的话,便宣告失败。
现在小鸟们遇到了一个难题,他们遇到了一堵巨大的墙,墙上仅有m个洞供
他们通过,由于小鸟们的体型不同且墙上洞的形状也不同,所以每种体型的鸟通
过每个洞的时间都不同,鸟的体型共有n种,第i种体型的鸟通过第j个洞需要的
时间记为T(i,j),且一个洞必须前一只鸟通过之后后一只鸟才能开始通过。
从时刻0开始,鸟开始通过,而每一只鸟的等待时间为从时刻0到自己已经通
过洞的时间。现在知道了第i种体型的鸟有pi只,请求出使所有鸟都通过墙的最
少的等待时间之和。
【输入格式】
第1行包含两个正整数n和m,表示鸟的体型的种数和墙洞的数量。
第2行包含n个正整数,其中第i个数为pi,表示点第i种体型的鸟的只数。
接下来有n行,每行包含m个非负整数,这n行中的第i行的第j个数为t(i,j),
表示第i种体型的鸟通过第j个墙洞所需的时间。输入文件中每行相邻的两个数之
间均由一个空格隔开,行末均没有多余空格。
【输出格式】
输出仅一行包含一个整数,为总等待时间的最小值。
【输入输出样例】
bird.in bird.out3 2
3 1 1
5 7
3 6
8 947
全国信息学奥林匹克联赛(NOIP2016) 复赛模拟 提高组
第 5 页 共5页
【数据范围】
每组数据的n、 m和p值如下:
对于 100%的数据, n<=40,m<=100,p<=800,t(i,j)<=1000(p 为鸟的总只数)
序号 n= m= p=1 5 5 102 40 1 4003 40 2 3004 40 40 405 5 40 1006 10 50 2007 20 60 4008 40 80 6009 40 100 80010 40 100 800
题解:
一个费用流的经典模型,对于这种问题,我们可以认为,对于一个洞,最后一个的鸟通
过的时间,只有他一个在等待,总答案贡献为 Time*1,倒数第二只鸟为 Time*2,一次类
推,于是我们可以建立出一张费用流的图
将源点连向 n 种鸟,费用 0,流量为这种鸟的 shuliang
将 m 个洞分别拆成 p 份,将这 m*p 个点连向汇点,费用 0,流量 1
将 n 种鸟分别连向 m*p 个洞的点,费用为 f(m,n)*1,f(m,n)*2,f(m,n)*3,……
,f(m,n)*p,流量为 1
然而 m*p 有 80000,n 有 40,连边有 3200000 条,所以需要优化,我们发现,一个洞的
f(m,n)*1 没有满流时,f(m,n)*2 一定没有用,于是我们可以一开始只将鸟连向每个洞的第
一个点,当一个点流满后,再在下一个点上建立新边,动态加边就可以过这道题了。
#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<map>using namespace std;typedef long long ll;const int oo=1e9; //无穷 const int mm=11111111; //边 const int mn=888888; //点 int node,src,dest,edge; int ver[mm],flow[mm],cost[mm],nex[mm]; int head[mn],dis[mn],p[mn],q[mn],vis[mn]; /**这些变量基本与最大流相同,增加了 cost 表示边的费用, p 记录可行流上节点对应的反向边 */ inline void prepare(int _node,int _src,int _dest) //预处理 点的个数 起点 终点 { node=_node,src=_src,dest=_dest; for(int i=0; i<node; i++)head[i]=-1,vis[i]=0; edge=0; } void addedge(int u,int v,int f,int c) { ver[edge]=v,flow[edge]=f,cost[edge]=c,nex[edge]=head[u],head[u]=edge++; ver[edge]=u,flow[edge]=0,cost[edge]=-c,nex[edge]=head[v],head[v]=edge++; } /**以上同最大流*/ /**spfa 求最短路,并用 p 记录最短路上的边*/ bool spfa() { int i,u,v,l,r=0,tmp; for(i=0; i<node; ++i)dis[i]=oo; dis[q[r++]=src]=0; p[src]=p[dest]=-1; for(l=0; l!=r; (++l>=mn)?l=0:l) for(i=head[u=q[l]],vis[u]=0; i>=0; i=nex[i]) if(flow[i]&&dis[v=ver[i]]>(tmp=dis[u]+cost[i])) { dis[v]=tmp; p[v]=i^1; if(vis[v]) continue; vis[q[r++]=v]=1; if(r>=mn)r=0; } return p[dest]>-1; } int num[45],cot[45][105],n,m,sum;/**源点到汇点的一条最短路即可行流,不断的找这样的可行流*/ int SpfaFlow() { int i,ret=0,delta; while(spfa()) { for(i=p[dest],delta=oo; i>=0; i=p[ver[i]]) if(flow[i^1]<delta)delta=flow[i^1]; for(i=p[dest]; i>=0; i=p[ver[i]]) flow[i]+=delta,flow[i^1]-=delta; ret+=delta*dis[dest]; int pt=ver[p[dest]]; int x=(pt-n-1)%sum+1,y=(pt-n+sum-1)/sum; if(x==sum)break; for(int i=1;i<=n;i++)addedge(i,n+(y-1)*sum+x+1,1,(x+1)*cot[i][y]); } return ret; } int main(){int i,j;scanf("%d%d",&n,&m);for(i=1;i<=n;i++)scanf("%d",&num[i]),sum+=num[i];prepare(n+sum*m+2,0,n+sum*m+1);for(i=1;i<=n;i++){addedge(0,i,num[i],0);for(j=1;j<=m;j++)scanf("%d",&cot[i][j]),addedge(i,n+(j-1)*sum+1,1,cot[i][j]);}for(i=1;i<=sum;i++){for(j=1;j<=m;j++)addedge(n+(j-1)*sum+i,n+sum*m+1,1,0);}printf("%d\n",SpfaFlow());return 0;} /*3 23 1 15 73 68 947*/
阅读全文
0 0
- NOIP 2016 费用流
- NOIP模拟:Box(费用流)
- NOIP模拟 放盒子【费用流】
- [NOIP模拟] 方盒子 费用流
- noip 志愿者招募 (费用流/抽象建图)
- [NOIP模拟][匈牙利算法][费用流]放盒子
- 费用流!
- 费用流
- 费用流
- 费用流
- 费用流
- noip 2016
- NOIP 2016
- noip式mengbier (noip 2016)
- BZOJ 1283: 序列 最大费用费用流
- 最小费用最大流
- 最小费用最大流
- 最小费用最大流
- MySQL中的表中增加删除字段
- Codeforces Round #383 (Div. 2) C. Arpa's loud Owf and Mehrdad's evil plan
- USB hub 多usb接口重映射:udev 规则
- mysql 存储日期问题
- Girls and Boys(二分图--匈牙利算法)
- NOIP 2016 费用流
- 3D transform (学习笔记)
- 拓扑,DP noip 模拟赛 [益智游戏] 题解
- 51 nod 1286 1286 三段子串(exkmp)
- C语言基础
- 避免全表扫描的sql优化
- 自动化测试脚本工具,在eclipse里加pydev插件,selenium
- 面向对象的几大原则
- 9.S5PV210移植stdio时Makefile的详解