2018.10.15 loj#6010. 「网络流 24 题」数字梯形(费用流)
传送门
费用流经典题。
按照题目要求建边。
为了方便我将所有格子拆点,三种情况下容量分别为111,infinfinf,infinfinf,费用都为validi,jval_{id_{i,j}}validi,j。
然后从源点向第一排的mmm个点连边,三种情况下容量都为111,费用都为0。
然后从最后一排的m+n−1m+n-1m+n−1个点向汇点连边,三种情况下容量为111,infinfinf,infinfinf,费用都为0。
至于格子之间的路径,三种情况下容量为111,111,infinfinf,费用都为0。
跑三次最大费用流就行了。
代码:
#include<bits/stdc++.h>
#define N 1005
#define M 20005
using namespace std;
inline int read(){
int ans=0;
char ch=getchar();
while(!isdigit(ch))ch=getchar();
while(isdigit(ch))ans=(ans<<3)+(ans<<1)+(ch^48),ch=getchar();
return ans;
}
int n,m,id[25][25],a[25][25],tot=0,all=0;
struct edge{int v,next,c,w;};
struct MCMF{
edge e[M<<1];
bool in[N];
int first[N],d[N],flow[N],pos[N],pred[N],cnt,s,t;
inline void init(){memset(first,-1,sizeof(first)),cnt=-1,s=0,t=all*2+1;}
inline void addedge(int u,int v,int c,int w){e[++cnt].v=v,e[cnt].w=w,e[cnt].c=c,e[cnt].next=first[u],first[u]=cnt;}
inline void add(int u,int v,int c,int w){addedge(u,v,c,w),addedge(v,u,0,-w);}
inline bool spfa(){
queue<int>q;
for(int i=0;i<=t;++i)d[i]=-0x3f3f3f3f;
in[s]=1,d[s]=0,pred[t]=-1,flow[s]=0x3f3f3f3f,q.push(s);
while(!q.empty()){
int x=q.front();
q.pop(),in[x]=0;
for(int i=first[x];~i;i=e[i].next){
int v=e[i].v;
if(e[i].c&&d[v]<d[x]+e[i].w){
d[v]=d[x]+e[i].w,flow[v]=min(flow[x],e[i].c),pred[v]=x,pos[v]=i;
if(!in[v])in[v]=1,q.push(v);
}
}
}
return d[t]!=-0x3f3f3f3f;
}
inline int solve(){
int ret=0;
for(int w=t;spfa();w=t){
ret+=d[t]*flow[t];
while(w!=s)e[pos[w]].c-=flow[t],e[pos[w]^1].c+=flow[t],w=pred[w];
}
return ret;
}
}mcmf;
int main(){
m=read(),n=read(),all=(m*2+n-1)*n/2;
for(int i=1;i<=n;++i)for(int j=1;j<=m+i-1;++j)id[i][j]=++tot,a[i][j]=read();
mcmf.init();
for(int i=1;i<=m;++i)mcmf.add(mcmf.s,id[1][i],1,0);
for(int i=1;i<n;++i)for(int j=1;j<=m+i-1;++j){
mcmf.add(id[i][j],id[i][j]+all,1,a[i][j]);
mcmf.add(id[i][j]+all,id[i+1][j],1,0);
mcmf.add(id[i][j]+all,id[i+1][j+1],1,0);
}
for(int i=1;i<=m+n-1;++i)mcmf.add(id[n][i],id[n][i]+all,1,a[n][i]),mcmf.add(id[n][i]+all,mcmf.t,1,0);
printf("%d\n",mcmf.solve());
mcmf.init();
for(int i=1;i<=m;++i)mcmf.add(mcmf.s,id[1][i],1,0);
for(int i=1;i<n;++i)for(int j=1;j<=m+i-1;++j){
mcmf.add(id[i][j],id[i][j]+all,0x3f3f3f3f,a[i][j]);
mcmf.add(id[i][j]+all,id[i+1][j],1,0);
mcmf.add(id[i][j]+all,id[i+1][j+1],1,0);
}
for(int i=1;i<=m+n-1;++i)mcmf.add(id[n][i],id[n][i]+all,0x3f3f3f3f,a[n][i]),mcmf.add(id[n][i]+all,mcmf.t,0x3f3f3f3f,0);
printf("%d\n",mcmf.solve());
mcmf.init();
for(int i=1;i<=m;++i)mcmf.add(mcmf.s,id[1][i],1,0);
for(int i=1;i<n;++i)for(int j=1;j<=m+i-1;++j){
mcmf.add(id[i][j],id[i][j]+all,0x3f3f3f3f,a[i][j]);
mcmf.add(id[i][j]+all,id[i+1][j],0x3f3f3f3f,0);
mcmf.add(id[i][j]+all,id[i+1][j+1],0x3f3f3f3f,0);
}
for(int i=1;i<=m+n-1;++i)mcmf.add(id[n][i],id[n][i]+all,0x3f3f3f3f,a[n][i]),mcmf.add(id[n][i]+all,mcmf.t,0x3f3f3f3f,0);
printf("%d",mcmf.solve());
return 0;
}
2018.10.15 loj#6010. 「网络流 24 题」数字梯形(费用流)的更多相关文章
- 2018.10.14 loj#6012. 「网络流 24 题」分配问题(费用流)
传送门 费用流水题. 依然是照着题意模拟建边就行了. 为了练板子又重新写了一遍费用流. 代码: #include<bits/stdc++.h> #define N 305 #define ...
- 2018.10.14 loj#6011. 「网络流 24 题」运输问题(费用流)
传送门 费用流入门题. 直接按照题意模拟. 把货物的数量当做容量建边. 然后跑一次最小费用流和最大费用流就行了. 代码: #include<bits/stdc++.h> #define N ...
- LOJ #6010. 「网络流 24 题」数字梯形
#6010. 「网络流 24 题」数字梯形 题目描述 给定一个由 n nn 行数字组成的数字梯形如下图所示.梯形的第一行有 m mm 个数字.从梯形的顶部的 m mm 个数字开始,在每个数字处可以 ...
- 【刷题】LOJ 6010 「网络流 24 题」数字梯形
题目描述 给定一个由 \(n\) 行数字组成的数字梯形如下图所示.梯形的第一行有 \(m\) 个数字.从梯形的顶部的 \(m\) 个数字开始,在每个数字处可以沿左下或右下方向移动,形成一条从梯形的顶至 ...
- 2018.10.15 loj#6013. 「网络流 24 题」负载平衡(费用流)
传送门 费用流sb题. 直接从sss向每个点连边,容量为现有物品量. 然后从ttt向每个点连边,容量为最后库存量. 由于两个点之间可以互相任意运送物品,因此相邻的直接连infinfinf的边就行了. ...
- Libre 6010「网络流 24 题」数字梯形 (网络流,最大费用最大流)
Libre 6010「网络流 24 题」数字梯形 (网络流,最大费用最大流) Description 给定一个由n 行数字组成的数字梯形如下图所示.梯形的第一行有m 个数字.从梯形的顶部的m 个数字开 ...
- 2018.10.14 loj#6003. 「网络流 24 题」魔术球(最大流)
传送门 网络流好题. 这道题可以动态建图. 不难想到把每个球iii都拆点成i1i_1i1和i2i_2i2,每次连边(s,i1),(i2,t)(s,i_1),(i_2,t)(s,i1),(i2, ...
- 【刷题】LOJ 6227 「网络流 24 题」最长k可重线段集问题
题目描述 给定平面 \(\text{xoy}\) 上 \(n\) 个开线段组成的集合 \(\text{I}\) ,和一个正整数 \(k\) ,试设计一个算法. 从开线段集合 \(\text{I}\) ...
- [luogu_P1251][LOJ#6008]「网络流 24 题」餐巾计划
[luogu_P1251][LOJ#6008]「网络流 24 题」餐巾计划 试题描述 一个餐厅在相继的 \(N\) 天里,第 \(i\) 天需要 \(R_i\) 块餐巾 \((i=l,2,-,N)\) ...
随机推荐
- 创建类type (底层代码)
类的创建时是用type 实现的 def __init__(self, name): self.name = name def fun(self): print("%s is talking' ...
- Mysql 日期类型 date、datetime、timestamp.
三种: date.datetime.timestamp. date : 格式 "YYYY-MM-DD" ,范围 "1000-00-00"到"9999 ...
- ABAP-BarCode-2-Excel打印二维码
以前用Excel打印过二维码看板标签,将实现过程备注下. 1.安装控件 安装文件:TBarCodeOffice.exe 2.控件注册 打开Excel,找到[选项] 在打开的界面选择[加载项],在活动应 ...
- 在JSP中,使用get提交方式出现乱码时,为什么要使用new String(s.getBytes("iso-8859-1"),"utf-8");?
最近在学JSP,在学习处理get方式提交数据出现乱码问题的时候,对其中的一个解决方法new String(s.getBytes("iso-8859-1"),"utf-8& ...
- 吴裕雄 实战python编程(1)
import sqlite3 conn = sqlite3.connect('E:\\test.sqlite') # 建立数据库联接cursor = conn.cursor() # 建立 cursor ...
- 删除临时表空间ora-25152错误
删除临时表空间,或者收缩临时表空间经常会出现表空间占用等情况. 下面我们就对这种情况进行处理, 首先查找被锁的sid: SELECT a.INST_ID,b.TABLESPACE , b.segfil ...
- CentOS 6.3安装配置supervisor进程管理工具
1. Supervisor是一个C/S系统,它可以在类unix操作系统让用户来监视和控制后台服务进程的数量,一个很重要的功能就是监控服务器的主要后台进程,并在出现问题是自动重启. 2. 根据服务器上的 ...
- oracle 使用正则表达式获取字符串中包含的数字
select REGEXP_REPLACE('字符串中包含的数字123,提取后就是123', '[^0-9]', '') from dual;
- iOS - xcode - label 字体自动根据宽高 显示完全
1. label 左右约束要给. 2.代码实现label.adjustsFontSizeToFitWidth = YES
- [leetcode]124. Binary Tree Maximum Path Sum二叉树最大路径和
Given a non-empty binary tree, find the maximum path sum. For this problem, a path is defined as any ...