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 ;
}

最新文章

  1. 11月8日PHP练习《留言板》
  2. python操作memcached以及分布式
  3. INNO安装卸载自动结束进程插件使用
  4. 年前辞职-WCF入门学习(3)
  5. redis 几种数据类型往数据库存数据和取数据的帮助类
  6. 评论 “App死亡潮:400万应用僵尸超八成,周期仅10月”
  7. spm_预处理实验记录
  8. GNU PID
  9. linux group
  10. 从汇编角度来理解linux下多层函数调用堆栈执行状态
  11. U7Linux文件与目录管理
  12. 读书笔记 effective c++ Item 13 用对象来管理资源
  13. vue.js的学习中的简单案例
  14. 【EXCEL-折线图】百折不挠 | 用EXCEL画出与众不同的折线图(曲线图)
  15. Codeforces Round #520
  16. Question Of AI Model Training
  17. BOUNDARIES AND SPACE
  18. 指令发布中如何实现new新消息的提醒?
  19. 指尖下的js ——多触式web前端开发之二:处理简单手势(转)
  20. jQuery的$ .ajax防止重复提交的方法

热门文章

  1. [学习笔记] numpy次成分分析和PCA降维
  2. 课堂笔记:HTML---------一般标签、常用标签
  3. POJ 3067 Japan 【树状数组经典】
  4. ASP.NET整体运行机制+asp.net请求管道+页面生命周期+MVC整体运行机制原理图
  5. 匿名union
  6. PL/SQL dev 工具连接远程服务器oracle注意点
  7. linux各种抓包情况说明
  8. (eclipse)统一文件编码和代码风格
  9. #leetcode刷题之路3-无重复字符的最长子串
  10. PTA 最多删除3个字符(DP) - 30分