数字梯形问题[网络流24题之16]
来源:互联网 发布:淘宝新品上架提醒 编辑:程序博客网 时间:2024/05/02 19:20
问题描述:
给定一个由
规则
规则
规则
编程任务:
对于给定的数字梯形,分别按照规则
数据输入:
第
结果输出:
输出共三行,分别是按照规则
输入文件示例:
2 5
2 3
3 4 5
9 10 9 1
1 1 10 1 1
1 1 10 12 1 1
输出文件示例:
66
75
77
分析:
记第
规则
1 :新增源S 和汇T
2 :在S 和(1,j)0(1<=j<=m) 之间连一条容量为1 ,权值为−ai,j 的有向边
3 :在(i,j)0(1<=i<=n,1<=j<i+m) 和(i,j)1 之间连一条容量为1 ,权值为0 的有向边
4 :在(i,j)1(1<=i<n,1<=j<i+m) 和(i+1,j)0 之间连一条容量为1 ,权值为−ai+1,j 的有向边
5 :在(i,j)1(1<=i<n,i<=j<i+m) 和(i+1,j+1)0 之间连一条容量为1 ,权值为−ai+1,j+1 的有向边
6 :在(n,j)1(1<=j<n+m) 和T 之间连一条容量为+∞ ,权值为0 的有向边
图中的最小费用最大流的相反数就是规则
规则
规则
代码:
#include <cstdio>#include <cstring>#include <algorithm>#include <queue>using namespace std; const int inf = 0x3f3f3f3f;int head[447],nxt[4747],to[4747],wei[4747],cost[4747],tot=1,tot1,tot2;queue<int >que;int dis[447],pre[447],pres[447];bool vis[447];int mark[47][47],a[47][47],re=0;int n,m;int used;void add(int,int,int,int);bool bfs();void dinic();int main(){ scanf("%d%d",&m,&n); for(int i=1;i<=n;++i) for(int j=1;j<=i+m-1;++j){ scanf("%d",&a[i][j]); mark[i][j] = ++re; add(mark[i][j]<<1,(mark[i][j]<<1)+1,1,0); } for(int i=1;i<n+m;++i) add((mark[n][i]<<1)+1,446,1,0); tot1 = tot; for(int i=1;i<n;++i) for(int j=1;j<m+i;++j){ add((mark[i][j]<<1)+1,mark[i+1][j]<<1,1,-a[i+1][j]); add((mark[i][j]<<1)+1,mark[i+1][j+1]<<1,1,-a[i+1][j+1]); } tot2 = tot; for(int i=1;i<=m;++i) add(445,mark[1][i]<<1,1,-a[1][i]); used = 0; while(bfs()) dinic(); printf("%d",-used); for(int i=2;i<tot;i+=2){ wei[i] += wei[i^1]; wei[i^1] = 0; } for(int i=2;i<tot1;++i) wei[i] = inf; used = 0; while(bfs()) dinic(); printf("\n%d",-used); for(int i=2;i<tot;i+=2){ wei[i] += wei[i^1]; wei[i^1] = 0; } for(int i=2;i<tot2;i+=2) wei[i] = inf; used = 0; while(bfs()) dinic(); printf("\n%d",-used); return 0;}void add(int from,int tp,int value,int spend){ ++tot;nxt[tot]=head[from];head[from]=tot;to[tot]=tp;wei[tot]=value;cost[tot]=spend; ++tot;nxt[tot]=head[tp];head[tp]=tot;to[tot]=from;wei[tot]=0;cost[tot]=-spend;}bool bfs(){ memset(vis,false,sizeof vis); memset(dis,0x3f,sizeof dis); dis[445] = 0; que.push(445); int now; do{ now = que.front(); vis[now] = false; que.pop(); for(int i=head[now];i;i=nxt[i]) if(dis[to[i]]>dis[now]+cost[i] && wei[i]){ dis[to[i]] = dis[now]+cost[i]; pre[to[i]] = now; pres[to[i]] = i; if(!vis[to[i]]){ vis[to[i]] = true; que.push(to[i]); } } }while(!que.empty()); return dis[446]!=inf;}void dinic(){ int now = 446; int low = inf; while(now != 445){ low = min(low,wei[pres[now]]); now = pre[now]; } used += low*dis[446]; now = 446; while(now != 445){ wei[pres[now]] -= low; wei[pres[now]^1] += low; now = pre[now]; }}
- 数字梯形问题[网络流24题之16]
- 【网络流24题】数字梯形问题
- [网络流24题]数字梯形问题
- 【网络流24题-16】数字梯形问题 费用流
- [网络流24题 #16]数字梯形问题
- 网络流16数字梯形问题
- 网络流24题16. 数字梯形问题
- 线性规划与网络流24题之数字梯形问题 最大权不相交路径
- 线性规划与网络流24——数字梯形问题
- 网络流二十四题之十六 —— 数字梯形问题(DIGIT)
- 【网络流24题】【cogs738】【codevs1913】数字梯形
- cogs 738. [网络流24题] 数字梯形
- 「网络流 24 题」数字梯形
- [网络流24题] 16 数字梯形(最大权不相交路径 ,最小费用最大流)
- 【网络流24题】数字梯形(二分图+最大费用流)
- loj6010「网络流 24 题」数字梯形(费用流)
- 数字梯形问题(最小费用流)
- nefu484数字梯形问题
- Linux raw socket 和 packet socket 的主要区别
- Android 自定义控件(一)
- 一步步学spark之一scala中面向对象的不同构造器使用2.1
- UISplitViewController使用记录
- 越狱[HNOI2008,bzoj1008]
- 数字梯形问题[网络流24题之16]
- java使用freemaker生成xml
- 对于linux下system()函数的深度理解(整理)
- SignalR(ASP.NET)实现推送功能
- CodeForces - 675B Restoring Painting (暴力&转换)水
- Win32 API备忘
- sk_buff结构分析
- 2014.4新版uboot启动流程分析
- \opencv\build\x86下的vc9,vc10、vc11、vc12是什么意思?