cogs 738. [网络流24题] 数字梯形
来源:互联网 发布:nginx宕机原因 编辑:程序博客网 时间:2024/05/17 12:03
- [网络流24题] 数字梯形
★★★ 输入文件:digit.in 输出文件:digit.out 简单对比
时间限制:1 s 内存限制:128 MB
«问题描述:
给定一个由n 行数字组成的数字梯形如下图所示。梯形的第一行有m 个数字。从梯形
的顶部的m 个数字开始,在每个数字处可以沿左下或右下方向移动,形成一条从梯形的顶
至底的路径。
规则1:从梯形的顶至底的m条路径互不相交。
规则2:从梯形的顶至底的m条路径仅在数字结点处相交。
规则3:从梯形的顶至底的m条路径允许在数字结点相交或边相交。
«编程任务:
对于给定的数字梯形,分别按照规则1,规则2,和规则3 计算出从梯形的顶至底的m
条路径,使这m条路径经过的数字总和最大。
«数据输入:
由文件digit.in提供输入数据。文件的第1 行中有2个正整数m和n(m,n<=20),分别
表示数字梯形的第一行有m个数字,共有n 行。接下来的n 行是数字梯形中各行的数字。
第1 行有m个数字,第2 行有m+1 个数字,…。
«结果输出:
程序运行结束时,将按照规则1,规则2,和规则3 计算出的最大数字总和输出到文件
digit.out中。每行一个最大总和。
输入文件示例 输出文件示例
digit.in
2 5
2 3
3 4 5
9 10 9 1
1 1 10 1 1
1 1 10 12 1 1
digit.out
66
75
77
【分析】
一道略微有点复杂的最大费用最大流…不过仔细一点还是很好想的
解法参见注释
【代码】
//cogs 738. [网络流24题] 数字梯形//1.拆点限制容量 //2.所有边(除了汇点直连边)容量为1//3.除了源点直连边容量为1,其它边容量为m//最大费用最大流 #include<iostream>#include<climits>#include<cstdio>#include<queue>#include<cstring>#define inf 1e9+7#define p(i,j) (i-1)*40+j#define M(a) memset(a,0,sizeof a)#define fo(i,j,k) for(i=j;i<=k;i++)using namespace std;const int mxn=10005;queue <int> q;bool vis[mxn]; int n,m,s,t,ans,cnt;int head[mxn],dis[mxn],pre[mxn],c[25][25];struct node {int from,to,d,next,flow;} f[mxn<<2]; inline void add(int u,int v,int flow,int d) { f[++cnt].to=v,f[cnt].from=u,f[cnt].next=head[u],f[cnt].flow=flow,f[cnt].d=d,head[u]=cnt; f[++cnt].to=u,f[cnt].from=v,f[cnt].next=head[v],f[cnt].flow=0,f[cnt].d=-d,head[v]=cnt;}inline bool spfa(){ int i,j,d,u,v,flow,ttt; memset(dis,-0x3f,sizeof dis);ttt=dis[0]; memset(vis,0,sizeof vis); dis[s]=0; q.push(s); while(!q.empty()) { u=q.front(); q.pop(); vis[u]=0; for(i=head[u];i;i=f[i].next) { v=f[i].to,flow=f[i].flow,d=f[i].d; if(dis[v]<dis[u]+d && flow>0) { dis[v]=dis[u]+d; pre[v]=i; //记录前驱边 if(!vis[v]) q.push(v),vis[v]=1; } } } return dis[t]>ttt;}inline void maxflow(){ int i,j,u,v,d,flow,tmp=inf; for(i=pre[t];i;i=pre[f[i].from]) tmp=min(tmp,f[i].flow); ans+=dis[t]*tmp; for(i=pre[t];i;i=pre[f[i].from]) { f[i].flow-=tmp; if(i&1) f[i+1].flow+=tmp; else f[i-1].flow+=tmp; }}int main(){ freopen("digit.in","r",stdin); freopen("digit.out","w",stdout); int i,j,k,u,v,w,d; scanf("%d%d",&m,&n); fo(i,1,n) fo(j,1,i+m-1) scanf("%d",&c[i][j]); s=0,t=2000; //1.不能相交 ——拆点 fo(j,1,m) add(s,p(1,j),1,c[1][j]); //add(p(1,i),p(1,i)+800,1,0); fo(i,1,n-1) fo(j,1,i+m-1) { add(p(i,j),p(i,j)+800,1,0); add(p(i,j)+800,p(i+1,j),1,c[i+1][j]); add(p(i,j)+800,p(i+1,j+1),1,c[i+1][j+1]); } fo(j,1,n+m-1) add(p(n,j),p(n,j)+800,1,0),add(p(n,j)+800,t,1,0); while(spfa()) maxflow(); printf("%d\n",ans); //2.仅有点相交,除了与汇点直连的点以外各边容量为1 M(head);M(pre);ans=cnt=0; fo(j,1,m) add(s,p(1,j),1,c[1][j]); fo(i,1,n-1) fo(j,1,i+m-1) { add(p(i,j),p(i+1,j),1,c[i+1][j]); add(p(i,j),p(i+1,j+1),1,c[i+1][j+1]); } fo(j,1,n+m-1) add(p(n,j),t,m,0); while(spfa()) maxflow(); printf("%d\n",ans); //3.随便跑,容量m(inf) M(head);M(pre);ans=cnt=0; fo(j,1,m) add(s,p(1,j),1,c[1][j]); fo(i,1,n-1) fo(j,1,i+m-1) { add(p(i,j),p(i+1,j),m,c[i+1][j]); add(p(i,j),p(i+1,j+1),m,c[i+1][j+1]); } fo(j,1,n+m-1) add(p(n,j),t,m,0); while(spfa()) maxflow(); printf("%d\n",ans); return 0;}/*2 52 33 4 59 10 9 11 1 10 1 1 1 1 10 12 1 1 */
0 0
- cogs 738. [网络流24题] 数字梯形
- 【网络流24题】数字梯形问题
- [网络流24题]数字梯形问题
- 【网络流24题-16】数字梯形问题 费用流
- [网络流24题 #16]数字梯形问题
- 【网络流24题】【cogs738】【codevs1913】数字梯形
- 数字梯形问题[网络流24题之16]
- 网络流24题16. 数字梯形问题
- 「网络流 24 题」数字梯形
- 线性规划与网络流24——数字梯形问题
- 【网络流24题】数字梯形(二分图+最大费用流)
- loj6010「网络流 24 题」数字梯形(费用流)
- 线性规划与网络流24题之数字梯形问题 最大权不相交路径
- 网络流16数字梯形问题
- [网络流24题] COGS 搭配飞行员
- cogs 732. [网络流24题] 试题库
- cogs 461. [网络流24题] 餐巾
- COGS 732. [网络流24题] 试题库
- Unity3D 0410(2)
- 排序算法类模板
- XMU 1040 Schedule 【拓扑排序】
- 关于出现错误:_tkinter.TclError: couldn't open "E:\Python系列\Python程序\Python安装.gif"tkinter中不能打开GIF格式图片的解决办法
- 两个栈实现队列 两个队列实现栈
- cogs 738. [网络流24题] 数字梯形
- 489
- ZOJ 3956 Course Selection System(01背包)
- 剪花布条 KMP
- macOS Sierra版本下Hadoop(2.7.3)为分布式环境的详细安装
- POJ 2481 Cows
- java加锁与同步方法
- 2017.4.10 学习记录与感想 (xss、ctf、学习感想)
- MySQL(五)--数据类型