2007: [Noi2010]海拔

https://www.lydsy.com/JudgeOnline/problem.php?id=2007

分析:

  平面图最小割。

  S在左下,T在右上,从S到T的一个路径使得路径右下方全是1,左上方全是0。

  一个问题:每个点的高度只能是0/1,所以有些边是一定不能选的,就让它连向S,不影响。

代码:

 /*
平面图最小割
*/
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<cctype>
#include<queue>
using namespace std;
typedef long long LL; inline int read() {
int x = , f = ; char ch = getchar(); for (; !isdigit(ch); ch=getchar()) if (ch=='-') f = -;
for (; isdigit(ch); ch=getchar()) x = x * + ch - ''; return x * f;
} const int N = ;
struct Edge{
int to, w, nxt;
Edge() {}
Edge(int a,int b,int c) {to = a, w = b, nxt = c;}
}e[];
struct Node{
int u;
LL dis;
Node() {}
Node(int a,LL b) {u = a, dis = b;}
bool operator < (const Node &A) const {
return dis > A.dis;
}
};
int head[N];
LL dis[N];
int Enum, n;
bool vis[N];
priority_queue<Node> q; void add_edge(int u,int v,int w) {
e[++Enum] = Edge(v, w, head[u]); head[u] = Enum;
// cout << u << " " << v << " " << w << '\n';
} int get(int i,int j) {
return (i - ) * n + j;
} int Dijkstra(int S,int T) {
for (int i=; i<=T; ++i) dis[i] = 1e18, vis[i] = false;
dis[S] = ;
q.push(Node(S,));
Node now, nxt;
while (!q.empty()) {
now = q.top(); q.pop();
int u = now.u;
if (vis[u]) continue;
vis[u] = true;
for (int i=head[u]; i; i=e[i].nxt) {
int v = e[i].to;
if (dis[v] > dis[u] + e[i].w) {
dis[v] = dis[u] + e[i].w;
q.push(Node(v,dis[v]));
}
}
}
return dis[T];
} int main() {
n = read();
int S = , T = n * n + ; for (int i=; i<=n+; ++i) { // 左 -> 右, 下 -> 上
for (int j=; j<=n; ++j) {
int w = read();
if (i == ) add_edge(get(i, j), T, w);
else if (i == n + ) add_edge(S, get(i - , j), w);
else add_edge(get(i, j), get(i - , j), w);
}
} for (int i=; i<=n; ++i) { // 上 -> 下 , 左 -> 右
for (int j=; j<=n+; ++j) {
int w = read();
if (j == ) add_edge(S, get(i, j), w);
else if (j == n + ) add_edge(get(i, j - ), T, w);
else add_edge(get(i, j - ), get(i, j), w);
}
} for (int i=; i<=n+; ++i) { // 右 -> 左 , 上 -> 下
for (int j=; j<=n; ++j) {
int w = read();
if (i == ) add_edge(T, get(i, j), w);
else if (i == n + ) add_edge(get(i - , j), S, w);
else add_edge(get(i - , j), get(i, j), w);
}
} for (int i=; i<=n; ++i) { // 下 -> 上 , 右 - > 左
for (int j=; j<=n+; ++j) {
int w = read();
if (j == ) add_edge(get(i, j), S, w);
else if (j == n + ) add_edge(T, get(i, j - ), w);
else add_edge(get(i, j), get(i, j - ), w);
}
}
printf("%d",Dijkstra(S, T));
return ;
}

2007: [Noi2010]海拔的更多相关文章

  1. BZOJ 2007: [Noi2010]海拔

    2007: [Noi2010]海拔 Time Limit: 20 Sec  Memory Limit: 552 MBSubmit: 2410  Solved: 1142[Submit][Status] ...

  2. 【BZOJ 2007】 2007: [Noi2010]海拔 (平面图转对偶图+spfa)

    2007: [Noi2010]海拔 Time Limit: 20 Sec  Memory Limit: 552 MBSubmit: 2504  Solved: 1195 Description YT市 ...

  3. 2007: [Noi2010]海拔 - BZOJ

    Description YT市是一个规划良好的城市,城市被东西向和南北向的主干道划分为n×n个区域.简单起见,可以将YT市看作一个正方形,每一个区域也可看作一个正方形.从而,YT城市中包括(n+1)× ...

  4. [BZOJ 2007] [Noi2010] 海拔 【平面图最小割(对偶图最短路)】

    题目链接:BZOJ - 2007 题目分析 首先,左上角的高度是 0 ,右下角的高度是 1.那么所有点的高度一定要在 0 与 1 之间.然而选取 [0, 1] 的任何一个实数,都可以用整数 0 或 1 ...

  5. BZOJ.2007.[NOI2010]海拔(最小割 对偶图最短路)

    题目链接 想一下能猜出,最优解中海拔只有0和1,且海拔相同的点都在且只在1个连通块中. 这就是个平面图最小割.也可以转必须转对偶图最短路,不然只能T到90分了..边的方向看着定就行. 不能忽略回去的边 ...

  6. bzoj 2007 [Noi2010]海拔——最小割转最短路

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2007 一个点的高度一定不是0就是1.答案一定形如一个左上角的连通块全是0的点.一个右下角的连 ...

  7. 【BZOJ】2007: [Noi2010]海拔(平面图转对偶图)

    题目 传送门:QWQ 分析 左上角是0,右下角是1.那么大概整张图是由0 1构成的. 那么我们要找到0和1的分界线,值就是最小割. 然后变成求原图最小割. 考虑到此题是平面图,那么就转成对偶图跑最短路 ...

  8. bzoj 2007: [Noi2010]海拔【最小割+dijskstra】

    上来就跑3e5的最大流--脑子抽了 很容易看出,每个地方的海拔都是0或1因为再高了没有意义,又,上去下来再上去没有意义,所以最后一定是从s连着一片0,剩下连着t一片1,然后有贡献的就是01交接的那些边 ...

  9. NOI2010海拔

    2007: [Noi2010]海拔 Time Limit: 20 Sec  Memory Limit: 552 MBSubmit: 1302  Solved: 612[Submit][Status] ...

随机推荐

  1. SQL-MySQL使用教程-对MySQL的初步尝试

    出现问题:中文无法显示.存储:不对任何数据做检测,只管理数据类型.

  2. C语言 返回指针的函数

    #include <stdio.h> char * test() { return "itcast"; } int main(int argc, const char ...

  3. SPOJ 694 不同子串个数

    一个论文题,求一个字符串有多少个不同的子串. 每个字符串可以看做一个后缀的前缀,然后,就转换为求每一个后缀中,不同的子串有多少. 每一个后缀,根据长度,可以提供len - sa[i] 个子串,但是,画 ...

  4. 动态规划(DP),压缩状态,插入字符构成回文字符串

    题目链接:http://poj.org/problem?id=1159 解题报告: 1.LCS的状态转移方程为 if(str[i-1]==str[j-1]) dp[i][j]=dp[i-1][j-1] ...

  5. 解决TextBox Ctrl+A不能全选的问题

    // 添加keyPress事件 private void textBox1_KeyPress(object sender, KeyPressEventArgs e) { if (e.KeyChar = ...

  6. Hibernate Validator数据校验框架常用注释

    使用前先配置maven,加入依赖: <dependency> <groupId>org.hibernate</groupId> <artifactId> ...

  7. Android学习笔记_13_网络通信之多个上传文件

    一.获取HTTP协议: 建立一个Web项目,建立一个如下所示的jsp界面,用IE捕获表单提交信息. <%@ page language="java" contentType= ...

  8. 一个JS对话框,可以显示其它页面,

    还不能自适应大小 garyBox.js // JavaScript Document// gary 2014-3-27// 加了 px 在google浏览器没加这个发现设置width 和height没 ...

  9. putty 启动 linux 下的oracle

    没搞过linux ,仅作记录: 1 打开putty.exe 程序 ,选择 连接 2 输入linux 的用户名和密码后,按下图操作: 3  启动监听 4 命令总结: 1.  sudo su - orac ...

  10. ffmpeg 学习

    1.ffmpeg使用语法 命令格式:    ffmpeg -i [输入文件名] [参数选项] -f [格式] [输出文件]    ffmpeg [[options][`-i' input_file]] ...