题目描述

设有 $N \times N$ 的方格图 $(N \le 9)$ ,我们将其中的某些方格中填入正整数,而其他的方格中则放入数字 $0$ 。如下图所示(见样例):

A
0 0 0 0 0 0 0 0
0 0 13 0 0 6 0 0
0 0 0 0 7 0 0 0
0 0 0 14 0 0 0 0
0 21 0 0 0 4 0 0
0 0 15 0 0 0 0 0
0 14 0 0 0 0 0 0
0 0 0 0 0 0 0 0
B

某人从图的左上角的 $A$ 点出发,可以向下行走,也可以向右走,直到到达右下角的 $B$ 点。在走过的路上,他可以取走方格中的数(取走后的方格中将变为数字 $0$ )。
此人从 $A$ 点到 $B$ 点共走两次,试找出 $2$ 条这样的路径,使得取得的数之和为最大。

输入输出格式

**输入格式:**

输入的第一行为一个整数 $N$ (表示 $N \times N$ 的方格图),接下来的每行有三个整数,前两个表示位置,第三个数为该位置上所放的数。一行单独的 $0$ 表示输入结束。

**输出格式:**
只需输出一个整数,表示 $2$ 条路径上取得的最大的和。
输入输出样例
> **输入样例#1:**
2 3 13
2 6 6
3 5 7
4 4 14
5 2 21
5 6 4
6 3 15
7 2 14
0 0 0
**输出样例#1:**
67

说明

NOIP 2000 提高组第四题

DP?不存在的

直接拆点建立两条边,值取反,跑最小费用最大流

#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#define maxn 100010
#define inf 0x3f3f3f3f
using namespace std;
int read()
{
int x=0,f=1;char s=getchar();
while('0'>s||s>'9') {if(s=='-') f=-1;s=getchar();}
while('0'<=s&&s<='9') {x=x*10+s-'0';s=getchar();}
return x*f;
}
int n,m,S,T;
int ans;
int map[10][10];
int from[maxn],dis[maxn],vis[maxn];
struct edge {
int u,v,nxt,spend,flow;
}e[maxn];
int head[maxn],tot=1;
void add_edge(int u,int v,int flow,int spend)
{
e[++tot].u=u;
e[tot].v=v;
e[tot].spend=spend;
e[tot].flow=flow;
e[tot].nxt=head[u];
head[u]=tot;
}
void add(int u,int v,int flow,int spend)
{
add_edge(u,v,flow,spend);
add_edge(v,u,0,-spend);
}
bool spfa()
{
memset(dis,inf,sizeof(dis));
memset(vis,0,sizeof(vis));
queue<int> q;
q.push(S);
dis[S]=0;
while(!q.empty())
{
int x=q.front();
q.pop();
vis[x]=0;
for(int i=head[x];i;i=e[i].nxt)
{
int v=e[i].v;
int u=e[i].u;
int f=e[i].flow;
int s=e[i].spend;
if(dis[v]>dis[u]+s&&f)
{
dis[v]=dis[u]+s;
from[v]=i;
if(!vis[v])
{
q.push(v);
vis[v]=1;
}
}
}
}
return dis[T]!=inf;
}
int maxflow;
void work()
{
int mn=inf;
for(int i=T;i!=S;i=e[from[i]].u)
mn=min(mn,e[from[i]].flow);
for(int i=T;i!=S;i=e[from[i]].u)
{
e[from[i]].flow-=mn;
e[from[i]^1].flow+=mn;
ans+=e[from[i]].spend*mn;
}
maxflow+=mn;
}
int calc(int i,int j)
{
return n*(i-1)+j;
}
int main()
{
scanf("%d",&n);
int a,b,c;
while(233)
{
a=read();
b=read();
c=read();
if(!a) break;
map[a][b]=c;
}
S=0;T=200;
add(S,1,2,0);
add(n*n+100,T,inf,0);
for(int i=1;i<=n;++i)
{
for(int j=1;j<=n;++j)
{
int newx=i+1;
int newy=j+1;
if(newx>=1&&newx<=n)
{
add(calc(i,j)+100,calc(newx,j),inf,0);
//printf("a[%d][%d]->a[%d][%d] ",i,j,newx,j);
} if(newy>=1&&newy<=n)
{
add(calc(i,j)+100,calc(i,newy),inf,0);
//printf("a[%d][%d]->a[%d][%d]",i,j,i,newy);
}
}
}
for(int i=1;i<=n;++i)
{
for(int j=1;j<=n;++j)
{
add(calc(i,j),calc(i,j)+100,1,-map[i][j]);
add(calc(i,j),calc(i,j)+100,1,0);
}
}
while(spfa()) work(); printf("%d",-ans);
return 0;
}

luogu 1004 方格取数的更多相关文章

  1. luogu 1004 方格取数 dp

    题目链接 题意 设有N*N的方格图(N<=9),我们将其中的某些方格中填入正整数,而其他的方格中则放入数字0.如下图所示: A 0 0 0 0 0 0 0 0 0 0 13 0 0 6 0 0 ...

  2. Libre 6007 「网络流 24 题」方格取数 / Luogu 2774 方格取数问题 (网络流,最大流)

    Libre 6007 「网络流 24 题」方格取数 / Luogu 2774 方格取数问题 (网络流,最大流) Description 在一个有 m*n 个方格的棋盘中,每个方格中有一个正整数.现要从 ...

  3. 【luogu P1004 方格取数】 题解

    题目链接:https://www.luogu.org/problemnew/show/P1004 标准的DP,不明白为什么有普及+提高的难度 四维DP[i][j][k][l] 表示第一遍走到i,j格子 ...

  4. LuoGu P1004 方格取数

    题目传送门 一开始这个题我是不会的(沙华弱DP啊QwQ),后来考完试我一想,这东西怎么和数字三角形那题这么像啊? 都是自上而下,只能向下或者向右,求一个max 那么...这不就是个走两遍的数字矩阵嘛 ...

  5. luogu P2774 方格取数问题

    有限制的问题,显然考虑全选再根据限制去掉的想法较优,我们发现一个点四周的点受限,其x或者y差一,也就是说奇偶性不同,那我们可以将其分成白点和黑点,就变成了最小割的问题,将每个白点向受限制的黑点连边,c ...

  6. P2774 方格取数问题 网络最大流 割

    P2774 方格取数问题:https://www.luogu.org/problemnew/show/P2774 题意: 给定一个矩阵,取出不相邻的数字,使得数字的和最大. 思路: 可以把方格分成两个 ...

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

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

  8. NOIP200003方格取数

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

  9. vijos 1563 疯狂的方格取数

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

随机推荐

  1. Parity game---poj1733

    Description Now and then you play the following game with your friend. Your friend writes down a seq ...

  2. Pots--poj(bfs,输出路径)

    http://poj.org/problem?id=3414 题意: 给你两个容量为a,b的杯子:有3个操作: 1:FILL(i):把第i个杯子从水库中装满: 2:DROP(i):把第i个杯子清空: ...

  3. linux,centOS,用LNMP搭建wordpress,更新固定连接--全流程

    下午到晚上的时间,买了个linux服务器,用的centOS系统,遇到各种问题! 1.用putty,ssh到vps后,根据网上命令,一步步下载并安装,具体步骤可以看一下网上教程,LNMP.org站上的教 ...

  4. UILabel富文本 段落格式以及UILabel添加图片

    之前文本整理有一点乱,这边重新整理一下,下面是效果图,一共两个UILabel, 富文本整理: /*NSForegroundColorAttributeName设置字体颜色,对象UIColor; NSP ...

  5. 加密货币 (Cryptocurrency) 市值 (market capitalization) 列表

    https://coinmarketcap.com/all/views/all/ ico 列表 https://www.icoalert.com/?q=&is_v=1 https://www. ...

  6. Scala系统学习(五):Scala访问修辞符

    本章将介绍Scala访问修饰符.包,类或对象的成员可以使用私有(private)和受保护(protected)的访问修饰符进行标注,如果不使用这两个关键字的其中一个,那么访问将被视为公开(public ...

  7. linq判断一个枚举的Name是否存在

    比如,枚举如下: [Serializable] public enum PayType : int { /// <summary> /// AAA /// </summary> ...

  8. http协议基础(八)请求首部字段

    请求首部字段 定义:请求首部字段是从客户端到服务器发送请求报文中所使用的字段,里面包含了附加信息.客户端信息以及对响应内容相关的优先级等内容 1.Accept 通知服务器用户代理可处理的媒体类型及媒体 ...

  9. How to install MVVM Light Toolkit via NuGet

    Here is how you can install MVVM Light Toolkit  via NuGet in an easy way using only Visual Studio. S ...

  10. JS的增删改查

    1.查 <script type="text/javascript"> /** * 查找 已经在html代码中存在的元素 */ /** * document.getEl ...