题目描述 Description
给出一个n*n的矩阵,每一格有一个非负整数Aij,(Aij <= )现在从(,)出发,可以往右或者往下走,最后到达(n,n),每达到一格,把该格子的数取出来,该格子的数就变成0,这样一共走K次,现在要求K次所达到的方格的数的和最大 输入描述 Input Description
第一行两个数n,k(<=n<=, <=k<=) 接下来n行,每行n个数,分别表示矩阵的每个格子的数 输出描述 Output Description
一个数,为最大和 样例输入 Sample Input 样例输出 Sample Output 数据范围及提示 Data Size & Hint
<=n<=, <=k<=

题目

芒果君:刚学的拆点,为数不多的自己写出来的网络流……理解题意后我们发现有以下几个要点:进行K次增广路;只能向右向下走;经过格点但可以不取数。那我们可以把每个格点拆成无权和有权的两个点。从其他点(同一位置有两个)走到该点,就走到无权点,流量视为inf,费用为0;当然也可以从同一点的无权走向有权,就是取出该数,只能取一次,流量是1,费用为负点权。左上连源点,右下连汇点。套KM的板子,最后的费用取相反数就是最大价值。注意建反边的费用是正边的相反数!

 #include<cstdio>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<stack>
#include<bitset>
#include<string>
#define maxn 20010
using namespace std;
typedef long long ll;
const int inf=<<;
queue<int>Q;
int n,cnt,hl[maxn],s,t,k,vis[maxn],dis[maxn],pre[maxn],flow[maxn],id[maxn],tot;
inline int cal(int x,int y){return (x-)*n+y;}
struct Edge{
int u,v,c,f,ne,ctr;
}e[];
void add(int u,int v,int c,int f,int ctr)
{
e[++cnt].u=u;
e[cnt].v=v;
e[cnt].c=c;
e[cnt].f=f;
e[cnt].ctr=cnt+ctr;
e[cnt].ne=hl[u];
hl[u]=cnt;
}
bool bfs()
{
for(int i=;i<=n*n*+;++i) dis[i]=inf,pre[i]=-,vis[i]=;
dis[s]=pre[s]=;
flow[s]=inf;
Q.push(s);
while(!Q.empty()){
int x=Q.front();
Q.pop();
vis[x]=;
for(int i=hl[x];i;i=e[i].ne){
int v=e[i].v,c=e[i].c,w=e[i].f;
if(c&&dis[v]>dis[x]+w){
dis[v]=dis[x]+w;
pre[v]=x;
id[v]=i;
flow[v]=min(flow[x],c);
if(!vis[v]){
vis[v]=;
Q.push(v);
}
}
}
}
return dis[t]<inf;
}
int KM()
{
int ret();
while(bfs()){
tot++;
if(tot>k) break;
int now=t;
while(now!=s){
int i=id[now],j=e[i].ctr;
e[i].c-=flow[t];
e[j].c+=flow[t];
now=pre[now];
}
ret+=flow[t]*dis[t];
}
return ret;
}
int main()
{
int w;
scanf("%d%d",&n,&k);
for(int i=;i<=n;++i)
for(int j=;j<=n;++j){
scanf("%d",&w);
add(cal(i,j),n*n+cal(i,j),,-w,);
add(n*n+cal(i,j),cal(i,j),,w,-);
}
puts("");
for(int i=;i<=n;++i)
for(int j=;j<=n;++j){
if(j+<=n){
add(cal(i,j),cal(i,j+),inf,,);
add(cal(i,j+),cal(i,j),,,-);
add(n*n+cal(i,j),cal(i,j+),,,);
add(cal(i,j+),n*n+cal(i,j),,,-);
}
if(i+<=n){
add(cal(i,j),cal(i+,j),inf,,);
add(cal(i+,j),cal(i,j),,,-);
add(n*n+cal(i,j),cal(i+,j),,,);
add(cal(i+,j),n*n+cal(i,j),,,-);
}
}
s=,t=n*n*+;
add(,,inf,,);add(,,,,-);
add(n*n,t,inf,,);add(t,n*n,,,-);
add(t-,t,inf,,);add(t,t-,,,-);
printf("%d\n",-KM());
return ;
}

codevs1227:方格取数2的更多相关文章

  1. [CodeVs1227]方格取数2(最大费用最大流)

    网络流24题的坑还没填完,真的要TJ? 题目大意:一个n*n的矩阵,每格有点权,从(1,1)出发,可以往右或者往下走,最后到达(n,n),每达到一格,把该格子的数取出来,该格子的数就变成0,这样一共走 ...

  2. codevs1227 方格取数2 注意数组啊啊啊啊啊啊啊啊啊啊

    一开始T了一组RE了一组,实在找不出错来,就把数组加了一个0竟然就多A了一组.很惊讶的又加了几个0最后竟然全A了!!! 懒得做了,改的是之前的那个蚯蚓的游戏问题.还是需要拆点,至于为什么不能重复走结点 ...

  3. HDU 1565&1569 方格取数系列(状压DP或者最大流)

    方格取数(2) Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total S ...

  4. NOIP200003方格取数

    NOIP200003方格取数 难度级别: D: 编程语言:不限:运行时间限制:1000ms: 运行空间限制:51200KB: 代码长度限制:2000000B 试题描述 XYZ 是首师大附中信息技术团编 ...

  5. vijos 1563 疯狂的方格取数

    P1653疯狂的方格取数 Accepted 标签:天才的talent[显示标签]   背景 Due to the talent of talent123,当talent123做完NOIP考了两次的二取 ...

  6. [HDU 1565+1569] 方格取数

    HDU 1565 方格取数(1) Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others ...

  7. 网络流(最大流) HDU 1565 方格取数(1) HDU 1569 方格取数(2)

      HDU 1565 方格取数(1) 给你一个n*n的格子的棋盘,每个格子里面有一个非负数.从中取出若干个数,使得任意的两个数所在的格子没有公共边,就是说所取的数所在的2个格子不能相邻,并且取出的数的 ...

  8. HDU-1565 方格取数(1)

    http://acm.hdu.edu.cn/showproblem.php?pid=1565 方格取数(1) Time Limit: 10000/5000 MS (Java/Others)    Me ...

  9. BZOJ 1475: 方格取数( 网络流 )

    本来想写道水题....结果调了这么久!就是一个 define 里面少加了个括号 ! 二分图最大点权独立集...黑白染色一下 , 然后建图 : S -> black_node , white_no ...

随机推荐

  1. bzoj 2430: [Poi2003]Chocolate 贪心

    发现每一次切割都会使另一方向所有切割次数++. 而每一刀的代价就是 cost*切割次数,故贪心按照cost从大到小排序即可. #include <bits/stdc++.h> #defin ...

  2. 自定义starter

    https://github.com/deadzq/spring-boot-starter-hello 父子项目 子项目引用父项目中的依赖和配置参数

  3. Array.prototype.xxx.call()处理字符串的疑惑

    看你不知道的JavaScript中卷 2.1数组时有个疑问.具体是这样的: 通过“借用”数组的方法可以很方便的处理字符串.可以“借用”数组的非变更方法,但不能“借用”数组的可变更方法. 用代码来描述就 ...

  4. c++学生信息管理系统(window控制台实现鼠标点击操作)

    翻起大一时写过的作业代码--一个学生信息管理系统,当时不会使用QT,不会MFC等库,只会c++,但是又想做一个有界面的,能够实现鼠标操作的程序.于是绞尽脑汁查资料,自己造轮子,最终写出来了下面的这个现 ...

  5. LSTM-航班人数预测

    小书匠深度学习LSTM 郑重声明,文章大部分翻译自: Time Series Prediction with LSTM Recurrent Neural Networks in Python with ...

  6. manjaro xfce4 使用super+D快捷键显示桌面(以及使用super+方向键调整窗口)设置无效

    xfce4 有两个地方设置快捷键:Keyboard -> application shortcuts 和 window manager -> keyboard. window manage ...

  7. 1、套按字及http基础知识之一

    MAC地址:设备到设备之间通信时专用(从源主机到目标主机可能经由N台路由设备)4 IP地址:标记主机到主机之间通信时专用 TCP/UDP :提供进程地址 通过port number来标记 进程地址:用 ...

  8. LOJ#2977. 「THUSCH 2017」巧克力(斯坦纳树+随机化)

    题目 题目 做法 考虑部分数据(颜色较少)的: 二分中位数\(mid\),将\(v[i]=1000+(v[i]>mid)\) 具体二分操作:然后求出包含\(K\)种颜色的联通快最小的权值和,判断 ...

  9. 在vscode里面光标跳跃的问题

    https://tieba.baidu.com/p/5242680781?red_tag=2439355674 卸载 JS-CSS-HTML Formatter就可以了.卸载完还要加载一下哦

  10. mkfs格式化分区(为分区写入文件系统)

    mkfs 命令非常简单易用,不过是不能调整分区的默认参数的(比如块大小是 4096 Bytes),这些默认参数除非特殊清况,否则不需要调整.如果想要调整,就需要使用 mke2fs 命令重新格式化.命令 ...