洛谷P1004 方格取数
网络流大法吼
不想用DP的我选择了用网络流……
建模方法:
从源点向(1,1)连一条容量为2(走两次),费用为0的边
从(n,n)向汇点连一条容量为2,费用为0的边
每个方格向右边和下边的方格连一条容量为inf,费用为0的边
走到每个方格,会取出方格上的数。每个方格的数只会被取走一次。
于是我们考虑拆点
每个方格向拆出的点连一条容量为1(只能被取走一次),费用为方格上的数的边
由于每个方格不一定只走一次,所以再连一条容量为inf,费用为0的边
然后跑最大费用最大流就行了~
我的代码中把边上的费用取相反数,跑最小费用最大流,最后得出的最小费用取负就是答案啦~!
下面是代码:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 210;
struct edge {
int flow, cap, cost, t, next;
}e[maxn * 50];
int n, m, s, t, p = -1, head[maxn], maxflow, mincost = 0, pre[maxn], dis[maxn], a[maxn][maxn];
bool vis[maxn];
void add_edge(int s, int t, int cap, int cost) {
p++;
e[p].t = t;
e[p].cap = cap;
e[p].cost = cost;
e[p].next = head[s];
head[s] = p;
}
bool spfa() {
queue < int > q;
while(!q.empty())q.pop();
memset(vis, 0, sizeof(vis));
vis[s] = 1;
q.push(s);
memset(dis, 0x7f, sizeof(dis));
memset(pre, -1, sizeof(pre));
dis[s] = 0;
while(!q.empty()) {
int k = q.front();
q.pop();
vis[k] = false;
for(int i = head[k]; i != -1; i = e[i].next) {
if(e[i].cap && dis[e[i].t] > dis[k] + e[i].cost) {
dis[e[i].t] = dis[k] + e[i].cost;
pre[e[i].t] = i;
if(!vis[e[i].t]) {
vis[e[i].t] = true;
q.push(e[i].t);
}
}
}
}
// for(int i = 0; i <= n * n; i++) cout << dis[i] << " ";
// cout << dis[t] << endl;
if(dis[t] == 0x7f7f7f7f) return false;
else return true;
}
void MCMF() {
while(spfa()) {
int mf = 0x7fffffff;
for(int i = pre[t]; i != -1; i = pre[e[i ^ 1].t]) {
mf = min(mf, e[i].cap);
// cout << i << " " << pre[e[i ^ 1].t] << endl;
// cout << e[2].cap << endl;
}
maxflow += mf;
for(int i = pre[t]; i != -1; i = pre[e[i ^ 1].t]) {
e[i].cap -= mf;
e[i ^ 1].cap += mf;
}
mincost += mf * dis[t];
}
}
int pos(int x, int y) {
return (x - 1) * n + y;
}
int main() {
memset(head, -1, sizeof(head));
cin >> n;
s = 0, t = maxn - 3;
int x, y, z;
while(1) {
cin >> x >> y >> z;
if(!(x || y || z)) break;
a[x][y] = z;
}
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= n; j++) {
add_edge(pos(i, j), pos(i, j) + n * n, 1, -a[i][j]);
add_edge(pos(i, j) + n * n, pos(i, j), 0, a[i][j]);
add_edge(pos(i, j), pos(i, j) + n * n, 0x7fffffff, 0);
add_edge(pos(i, j) + n * n, pos(i, j), 0, 0);
if(i < n) {
add_edge(pos(i, j) + n * n, pos(i + 1, j), 0x7fffffff, 0);
add_edge(pos(i + 1, j), pos(i, j) + n * n, 0, 0);
}
if(j < n) {
add_edge(pos(i, j) + n * n, pos(i, j + 1), 0x7fffffff, 0);
add_edge(pos(i, j + 1), pos(i, j) + n * n, 0, 0);
}
}
}
add_edge(s, pos(1, 1), 2, 0);
add_edge(pos(1, 1), s, 0, 0);
add_edge(pos(n, n) + n * n, t, 2, 0);
add_edge(t, pos(n, n) + n * n, 0, 0);
MCMF();
cout << -mincost << endl;
return 0;
}
qwq
洛谷P1004 方格取数的更多相关文章
- 棋盘DP三连——洛谷 P1004 方格取数 &&洛谷 P1006 传纸条 &&Codevs 2853 方格游戏
P1004 方格取数 题目描述 设有N $\times N$N×N的方格图(N $\le 9$)(N≤9),我们将其中的某些方格中填入正整数,而其他的方格中则放入数字00.如下图所示(见样例): A ...
- 洛谷 P1004 方格取数 题解
P1004 方格取数 题目描述 设有 \(N \times N\) 的方格图 \((N \le 9)\),我们将其中的某些方格中填入正整数,而其他的方格中则放入数字\(0\).如下图所示(见样例): ...
- 洛谷 P1004 方格取数 【多进程dp】
题目链接:https://www.luogu.org/problemnew/show/P1004 题目描述 设有N*N的方格图(N<=9),我们将其中的某些方格中填入正整数,而其他的方格中则放 ...
- 洛谷 P1004 方格取数
题目描述 设有N*N的方格图(N<=9),我们将其中的某些方格中填入正整数,而其他的方格中则放 人数字0.如下图所示(见样例): A 0 0 0 0 0 0 0 0 0 0 13 0 0 6 0 ...
- 【动态规划】洛谷P1004方格取数
题目描述 设有N*N的方格图(N<=9),我们将其中的某些方格中填入正整数,而其他的方格中则放 人数字0.如下图所示(见样例): A 0 0 0 0 0 0 0 0 0 0 13 0 0 6 0 ...
- 洛谷P1004 方格取数-四维DP
题目描述 设有 N \times NN×N 的方格图 (N \le 9)(N≤9) ,我们将其中的某些方格中填入正整数,而其他的方格中则放入数字 00 .如下图所示(见样例): A 0 0 0 0 0 ...
- Codevs 1043 ==洛谷 P1004 方格取数
题目描述 设有N*N的方格图(N<=9),我们将其中的某些方格中填入正整数,而其他的方格中则放 人数字0.如下图所示(见样例): A 0 0 0 0 0 0 0 0 0 0 13 0 0 6 0 ...
- 洛谷 P1004 方格取数 【多线程DP/四维DP/】
题目描述(https://www.luogu.org/problemnew/show/1004) 设有N*N的方格图(N<=9),我们将其中的某些方格中填入正整数,而其他的方格中则放 人数字0. ...
- 四维动规 洛谷P1004方格取数
分析:这个题因为数据量非常小,可以直接用四维的DP数组 dp[i][j][k][l]表示第一个人走到位置(i,j),第二个人走到位置[k][l]时所取的数的最大和 状态转移方程可以轻松得出为:dp[i ...
随机推荐
- AJAX发送POST请求,请求提交后Method从POST变成GET
服务器如果返回301或者302状态码,所有请求方法都会切换成GET头部的location如果要保证重定向后的请求方法,需要在服务端返回307(临时)或者308(永久)状态码,这两个状态码不会更改原请求 ...
- 《AndroidStudio每日一贴》3.高速切换代码风格、配色方案和键盘
<AndroidStudio每日一贴>3.高速切换代码风格.配色方案和键盘 高速切换代码风格.配色方案和键盘,使用快捷键: control + ~ 很多其它有用技巧请查看<Andro ...
- 【Android 系统开发】使用 Source InSight 阅读 Android 源代码
1. 安装 Source Insight (1) Source Insight 相关资源 安装相关资源 : -- 下载地址 : http://www.sourceinsight.com/down35. ...
- Codeforces Beta Round #29 (Div. 2, Codeforces format) C. Mail Stamps 拓扑排序
C. Mail Stamps One day Bob got a letter in an envelope. Bob knows that when Berland's post offic ...
- Chrome下使用百度地图报错Cannot read property 'minZoom' of undefined
问题:工作中在Google chome下面的js console里面测试百度地图API var map = new BMap.Map("container"); map.cente ...
- iOS 权限判断 跳转对应设置界面
相机权限 1.1 使用说明 在合适的地方导入#import <AVFoundation/AVFoundation.h> 使用AVAuthorizationStatus类获取当前权限状态 在 ...
- IPK僵尸网络 看看其传播手法
转自:http://www.freebuf.com/vuls/154975.html 一.IPK僵尸网络概述 IPK僵尸家族是自2012年底就开始出现并长期持续活跃在境外的DDoS僵尸网络.2016年 ...
- poj--1383--Labyrinth(树的直径)
Labyrinth Time Limit: 2000MS Memory Limit: 32768K Total Submissions: 4062 Accepted: 1529 Descrip ...
- 【POJ 2828】Buy Tickets
[题目链接] http://poj.org/problem?id=2828 [算法] 离线用线段树维护序列即可 [代码] #include <algorithm> #include < ...
- jetty服务器数据源配置JNDI-Oracle,MySQL,SQLServer,DB2等 (转)
下载jetty 下载jetty服务器(8.1.0.RC2),解压到任意目录下 http://dist.codehaus.org/jetty/jetty-hightide-8.1.0/jetty-hig ...