【BZOJ-2007】海拔 最小割 (平面图转对偶图 + 最短路)

时间:2022-09-20 17:35:15

2007: [Noi2010]海拔

Time Limit: 20 Sec  Memory Limit: 552 MB
Submit: 2095  Solved: 1002
[Submit][Status][Discuss]

Description

YT市是一个规划良好的城市,城市被东西向和南北向的主干道划分为n×n个区域。简单起见,可以将YT市看作一个正方形,每一个区域也可看作一个正方形。从而,YT城市中包括(n+1)×(n+1)个交叉路口和2n×(n+1)条双向道路(简称道路),每条双向道路连接主干道上两个相邻的交叉路口。下图为一张YT市的地图(n = 2),城市被划分为2×2个区域,包括3×3个交叉路口和12条双向道路。 小Z作为该市的市长,他根据统计信息得到了每天上班高峰期间YT市每条道路两个方向的人流量,即在高峰期间沿着该方向通过这条道路的人数。每一个交叉路口都有不同的海拔高度值,YT市市民认为爬坡是一件非常累的事情,每向上爬h的高度,就需要消耗h的体力。如果是下坡的话,则不需要耗费体力。因此如果一段道路的终点海拔减去起点海拔的值为h(注意h可能是负数),那么一个人经过这段路所消耗的体力是max{0, h}(这里max{a, b}表示取a, b两个值中的较大值)。 小Z还测量得到这个城市西北角的交叉路口海拔为0,东南角的交叉路口海拔为1(如上图所示),但其它交叉路口的海拔高度都无法得知。小Z想知道在最理想的情况下(即你可以任意假设其他路口的海拔高度),每天上班高峰期间所有人爬坡所消耗的总体力和的最小值。

Input

第一行包含一个整数n,含义如上文所示。 接下来4n(n + 1)行,每行包含一个非负整数分别表示每一条道路每一个方向的人流量信息。输入顺序:n(n + 1)个数表示所有从西到东方向的人流量,然后n(n + 1)个数表示所有从北到南方向的人流量,n(n + 1)个数表示所有从东到西方向的人流量,最后是n(n + 1)个数表示所有从南到北方向的人流量。对于每一个方向,输入顺序按照起点由北向南,若南北方向相同时由西到东的顺序给出(参见样例输入)。

Output

仅包含一个数,表示在最理想情况下每天上班高峰期间所有人爬坡所消耗的总体力和(即总体力和的最小值),结果四舍五入到整数。

Sample Input

1
1
2
3
4
5
6
7
8

Sample Output

3
【样例说明】
样例数据见下图。
最理想情况下所有点的海拔如上图所示。
【数据规模】
对于20%的数据:n ≤ 3;
对于50%的数据:n ≤ 15;
对于80%的数据:n ≤ 40;
对于100%的数据:1 ≤ n ≤ 500,0 ≤ 流量 ≤ 1,000,000且所有流量均为整数。

HINT

Source

Solution

典型的平面图,所以肯定利用其性质

很BZOJ1001狼爪兔子很像,直接平面图转对偶图求最短路即为最小割,那么就比较简单了

Code

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<queue>
using namespace std;
int read()
{
int x=,f=; char ch=getchar();
while (ch<'' || ch>'') {if (ch=='-') f=-; ch=getchar();}
while (ch>='' && ch<='') {x=x*+ch-''; ch=getchar();}
return x*f;
}
#define maxn 250010
int n;
struct EdgeNode{int next,to,len;}edge[maxn*];
int head[maxn],cnt;
void add(int u,int v,int w) {cnt++; edge[cnt].to=v; edge[cnt].next=head[u]; head[u]=cnt; edge[cnt].len=w;}
void insert(int u,int v,int w) {add(u,v,w);}
bool visit[maxn]; int dis[maxn],S,T;
#define inf 0x7fffffff
void spfa()
{
queue<int>q;
for (int i=S; i<=T; i++) dis[i]=inf;
q.push(S); visit[S]=; dis[S]=;
while (!q.empty())
{
int now=q.front(); q.pop(); visit[now]=;
for (int i=head[now]; i; i=edge[i].next)
if (dis[edge[i].to]>dis[now]+edge[i].len)
{
dis[edge[i].to]=dis[now]+edge[i].len;
if (!visit[edge[i].to])
visit[edge[i].to]=,q.push(edge[i].to);
}
}
}
int loc(int x,int y) {return (x-)*n+y;}
int main()
{
n=read(); S=,T=n*n+;
for (int i=; i<=n+; i++)
for (int x,j=; j<=n; j++)
{
x=read();
if (i==) insert(loc(i,j),T,x); else if (i==n+) insert(S,loc(i-,j),x); else insert(loc(i,j),loc(i-,j),x);
}
for (int i=; i<=n; i++)
for (int x,j=; j<=n+; j++)
{
x=read();
if (j==) insert(S,loc(i,j),x); else if (j==n+) insert(loc(i,j-),T,x); else insert(loc(i,j-),loc(i,j),x);
}
for (int i=; i<=n+; i++)
for (int x,j=; j<=n; j++)
{
x=read();
if (i==) insert(T,loc(i,j),x); else if (i==n+) insert(loc(i-,j),S,x); else insert(loc(i-,j),loc(i,j),x);
}
for (int i=; i<=n; i++)
for (int x,j=; j<=n+; j++)
{
x=read();
if (j==) insert(loc(i,j),S,x); else if (j==n+) insert(T,loc(i,j-),x); else insert(loc(i,j),loc(i,j-),x);
}
spfa();
printf("%d\n",dis[T]);
return ;
}

写spfa的sb选手...跑出dijkstra的10倍时间了....

【BZOJ-2007】海拔 最小割 (平面图转对偶图 + 最短路)的更多相关文章

  1. bzoj 1001 原图最小割转化为对偶图最短路

    题目大意: 现在小朋友们最喜欢的"喜羊羊与灰太狼",话说灰太狼抓羊不到,但抓兔子还是比较在行的, 而且现在的兔子还比较笨,它们只有两个窝,现在你做为狼王,面对下面这样一个网格的地形 ...

  2. BZOJ 1001 狼抓兔子 (网络流最小割&sol;平面图的对偶图的最短路)

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1001 算法讨论: 1.可以用最大流做,最大流等于最小割. 2.可以把这个图转化其对偶图,然 ...

  3. BZOJ 2007 海拔&lpar;平面图最小割转对偶图最短路&rpar;

    首先注意到,把一个点的海拔定为>1的数是毫无意义的.实际上,可以转化为把这些点的海拔要么定为0,要么定为1. 其次,如果一个点周围的点的海拔没有和它相同的,那么这个点的海拔也是可以优化的,即把这 ...

  4. BZOJ&period;2007&period;&lbrack;NOI2010&rsqb;海拔&lpar;最小割 对偶图最短路&rpar;

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

  5. BZOJ 2007 海拔(平面图最小割-最短路)

    题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=2007 题意:给出一个n*n的格子,那么顶点显然有(n+1)*(n+1)个.每两个相邻顶点 ...

  6. bzoj 1001 平面图转对偶图 最短路求图最小割

    原题传送门http://www.lydsy.com/JudgeOnline/problem.php?id=1001 整理了下之前A的题 平面图可以转化成对偶图,然后(NlogN)的可以求出图的最小割( ...

  7. bzoj 2007 &lbrack;Noi2010&rsqb;海拔——最小割转最短路

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

  8. bzoj1001&sol;luogu4001 狼抓兔子 &lpar;最小割&sol;平面图最小割转对偶图最短路&rpar;

    平面图转对偶图:先在原图中加一个s->t的边,然后对每个面建一个点,对每条分隔两个面的边加一条连接这两个面对应点的边,边权等于原边权. 然后从刚才加的s->t分割出来的两面对应的两个点跑最 ...

  9. 【bzoj2007】&lbrack;Noi2010&rsqb;海拔 最小割&plus;对偶图&plus;最短路

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

随机推荐

  1. 【BZOJ】1535&colon; &lbrack;POI2005&rsqb;Sza-Template

    题意 给一个串\(s(1 \le |s| \le 500000)\),求一个最长的串,使得这个串能覆盖整个串(可以重叠). 分析 首先这个串肯定是前缀也肯定是后缀. 题解 对串kmp后,建立\(fai ...

  2. 拖拽碰撞效果,高级浏览器下全部搞定(ie6-8还没有搞定)

    <!DOCTYPE HTML> <html lang="en-US"> <head> <meta charset="UTF-8& ...

  3. 第三十讲:Android之Animation(五)

    天行健,君子以自强不息.--<周易·乾·象> 本讲内容:逐帧动画 Frame Animation 逐帧动画 Frame Animation就是说一帧一帧的连起来播放就变成了动画,和放电影的 ...

  4. 图像切换器(ImageSwitcer)的功能与用法

    ImageSwitcher继承了VewSwitcher,因此它具有与ViewSwitcher相同的特征,可以在切换View组件时使用动画效果.ImageSwitcher继承了ViewSwitcher并 ...

  5. spark与hive的集成

    一:介绍 1.在spark编译时支持hive 2.默认的db 当Spark在编译的时候给定了hive的支持参数,但是没有配置和hive的集成,此时默认使用hive自带的元数据管理:Derby数据库. ...

  6. 关于SpringMVC

    SpringMVC 原理:1.用户发送请求给服务器.url:user.do2.服务器收到请求.发现DispatchServlet可以处理.于是调用DispatchServlet.3.DispatchS ...

  7. CentOS中安装Nginx

    一.背景 最近在写一些自己的项目,用到了nginx,所以自己动手来在Centos7上安装nginx,以下是安装步骤. 二.基本概念以及应用场景 1.什么是nginx Nginx是一款使用C语言开发的高 ...

  8. topcoder srm 500 div1

    problem1 link 如果decisions的大小为0,那么每一轮都是$N$个人.答案为0. 否则,如果答案不为0,那么概率最大的一定是一开始票数最多的人.因为这个人每一轮都在可以留下来的人群中 ...

  9. ltrace命令详解

    原文链接:https://ipcmen.com/ltrace 用来跟踪进程调用库函数的情况 补充说明 NAME       ltrace - A library call tracer ltrace命 ...

  10. 树形dp&amp&semi;&amp&semi;树的重心(D - Godfather POJ - 3107)

    题目链接:https://cn.vjudge.net/contest/277955#problem/D 题目大意:求树的重心(树的重心指的是树上的某一个点,删掉之后形成的多棵树中节点数最大值最小). ...