【BZOJ 2007】 2007: [Noi2010]海拔 (平面图转对偶图+spfa)
2007: [Noi2010]海拔
Time Limit: 20 Sec Memory Limit: 552 MB
Submit: 2504 Solved: 1195Description
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
8Sample Output
3【样例说明】
样例数据见下图。最理想情况下所有点的海拔如上图所示。
对于100%的数据:1 ≤ n ≤ 500,0 ≤ 流量 ≤ 1,000,000且所有流量均为整数。HINT
Source
【分析】
跟狼抓兔子差不多?
首先,大胆地考虑一下只有1和0?【如果不是,你可以假设一下只有一个点不是,周围都是,然后往好的地方修改,至少不会变差的】
当然你也不会无聊到1,0,1,0,交替。。不然累死人【其实最好就是都是平的,但是规定了两个角是有高度差的】
所以只要找到0,1分界线,就变成了最小割了。
但这种图嘛,可以转化成成对偶图,跑最短路就好了【别人说卡spfa?但是我过了】
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
using namespace std;
#define Maxn 510 int num[Maxn][Maxn],cnt; struct node
{
int x,y,c,next;
}t[Maxn*Maxn*];
int first[Maxn*Maxn*],len;
void ins(int x,int y,int c)
{
// printf("%d -> %d %d\n",x,y,c);
t[++len].x=x;t[len].y=y;t[len].c=c;
t[len].next=first[x];first[x]=len;
} queue<int > q;
bool inq[Maxn*Maxn*];
int dis[Maxn*Maxn*],st,ed;
bool spfa()
{
while(!q.empty()) q.pop();
memset(inq,,sizeof(inq));
for(int i=;i<=ed;i++) dis[i]=-;
inq[st]=;dis[st]=;
q.push(st);
while(!q.empty())
{
int x=q.front();
for(int i=first[x];i;i=t[i].next)
{
int y=t[i].y;
if(dis[y]==-||dis[y]>dis[x]+t[i].c)
{
dis[y]=dis[x]+t[i].c;
if(!inq[y])
{
q.push(y);
inq[y]=;
}
}
}q.pop();inq[x]=;
}
if(dis[ed]==-) return ;
return ;
} int main()
{
int n;
scanf("%d",&n);
for(int i=;i<=n;i++)
for(int j=;j<=n;j++) num[i][j]=++cnt;
for(int i=;i<=n;i++) num[i][]=cnt+;
for(int i=;i<=n;i++) num[n+][i]=cnt+;
len=;
memset(first,,sizeof(first));
for(int i=;i<=n+;i++)
for(int j=;j<=n;j++)
{
int x;scanf("%d",&x);
ins(num[i-][j],num[i][j],x);
}
for(int i=;i<=n;i++)
for(int j=;j<=n+;j++)
{
int x;scanf("%d",&x);
ins(num[i][j],num[i][j-],x);
}
for(int i=;i<=n+;i++)
for(int j=;j<=n;j++)
{
int x;scanf("%d",&x);
ins(num[i][j],num[i-][j],x);
}
for(int i=;i<=n;i++)
for(int j=;j<=n+;j++)
{
int x;scanf("%d",&x);
ins(num[i][j-],num[i][j],x);
}
st=;ed=cnt+;
// st=cnt+1;ed=0;
spfa();
printf("%d\n",dis[ed]);
return ;
}
2017-03-29 08:11:42
平面图转对偶图总结:
转自:http://blog.sina.com.cn/s/blog_60707c0f01011fnn.html
利用欧拉公式和数学归纳法可以证明平面图G的所有面的度之和等于其边数|E|的2倍,即:

1 最大流的应用
【BZOJ 2007】 2007: [Noi2010]海拔 (平面图转对偶图+spfa)的更多相关文章
- BZOJ2007 NOI2010 海拔 平面图转对偶图 最小割
题面太长啦,请诸位自行品尝—>海拔 分析: 这是我见过算法比较明显的最小割题目了,很明显对于某一条简单路径,海拔只会有一次变换. 而且我们要最终使变换海拔的边权值和最小. 我们发现变换海拔相当于 ...
- [NOI2010]海拔 平面图转对偶图 最小割
题解: 首先,我们不难猜到高度只有 $0$ 或 $1$ 两种可能,而且高度为 0 的地区组成一个联通块,高度为 1 的地区组成一个联通块.只有这样,人们所耗费的体力才是最小的.得出这个结论,题目就成了 ...
- P2046 [NOI2010]海拔 平面图转对偶图(最小割-》最短路)
$ \color{#0066ff}{ 题目描述 }$ YT市是一个规划良好的城市,城市被东西向和南北向的主干道划分为n×n个区域.简单起见,可以将YT市看作 一个正方形,每一个区域也可看作一个正方形. ...
- Vijos1734 NOI2010 海拔 平面图最小割
建立平面图的对偶图,把最小割转化成最短路问题 Dijkstra算法堆优化 (被输入顺序搞WA了好几次T_T) #include <cstdio> #include <cstring& ...
- bzoj 4541: [Hnoi2016]矿区【平面图转对偶图+生成树】
首先平面图转对偶图,大概思路是每条边存正反,每个点存出边按极角排序,然后找每条边在它到达点的出边中极角排序的下一个,这样一定是这条边所属最小多边形的临边,然后根据next边找出所有多边形,用三角剖分计 ...
- BZOJ.2007.[NOI2010]海拔(最小割 对偶图最短路)
题目链接 想一下能猜出,最优解中海拔只有0和1,且海拔相同的点都在且只在1个连通块中. 这就是个平面图最小割.也可以转必须转对偶图最短路,不然只能T到90分了..边的方向看着定就行. 不能忽略回去的边 ...
- Luogu2046 NOI2010 海拔 平面图、最小割、最短路
传送门 首先一个不知道怎么证的结论:任意点的\(H\)只会是\(0\)或\(1\) 那么可以发现原题的本质就是一个最小割,左上角为\(S\),右下角为\(T\),被割开的两个部分就是\(H=0\)与\ ...
- 【bzoj2007】[Noi2010]海拔 最小割+对偶图+最短路
题目描述 YT市是一个规划良好的城市,城市被东西向和南北向的主干道划分为n×n个区域.简单起见,可以将YT市看作一个正方形,每一个区域也可看作一个正方形.从而,YT城市中包括(n+1)×(n+1)个交 ...
- NOI 2010 海拔 ——平面图转对偶图
[题目分析] 可以知道,所有的海拔是0或1 最小割转最短路,就可以啦 SPFA被卡,只能换DIJ [代码] #include <cstdio> #include <cstring&g ...
随机推荐
- 01 DIV+CSS 固定页面布局
本文讲解使用DIV+CSS布局最基本的内容,读完本文你讲会使用DIV+CSS进行简单的页面布局. DIV+CSS布局中主要CSS属性介绍: Float: Float属性是DIV+CSS布局中最基本也是 ...
- laravel前台html代码不显示
后天向前台传输变量,如果能取到变量数据,还有代码,但是不显示图片 可以把{{}}换成{!! !!}试试.
- LintCode之二叉树的最大节点
分治问题,可以把整棵树看做是由一颗颗只有三个节点组成的小树,一颗树的构成是根节点.左子树.右子树,这样只需要从左子树找出一个最大的节点,从右子树找出一个最大的节点,然后与根节点三个取个最大的,就是最终 ...
- Vue笔记之模板语法
插值 比较常用的就是插值,插值就是{{ foobar }}用两个大括号包起来的一个变量,显示的时候会将双大括号标签替换为这个变量的值. 基本的用法就是: <p>{{ message }}& ...
- 打表找规律C - Insertion Sort Gym - 101955C
题目链接:https://cn.vjudge.net/contest/273377#problem/C 给你 n,m,k. 这个题的意思是给你n个数,在对前m项的基础上排序的情况下,问你满足递增子序列 ...
- IT人员必备linux安全运维之Ssh用途、安全性、身份认证以及配置……【转】
SSH一般用途 提供shell,解决telnet不安全的传输 1.修改默认ssh默认端口 vi /etc/ssh/sshd_config 修改之后重启 >systemctl restart ss ...
- UVALive 5760 Alice and Bob
题意是黑板上有n个数\(S_i\).每次操作可以把其中一个数减1或者将两个数合并为一个数.一个数变为0时,则不能再对其操作. 思路是发现最大的可操作次数为\( \sum S_i\)+(n - 1).\ ...
- [转载]hazard pointer
hazard pointer 转载自: http://hi.baidu.com/rodimus/item/f6539cc179894f2f47d5c0ef 这是用于解决多线程并发下内存的回收,一块内存 ...
- Android仿新浪新闻SlidingMenu界面的实现 .
先看看原图: 如图所示,这种侧滑效果以另一种方式替代了原先tab导航的那种用户体验方式 给人耳目一新的感觉,现已被广大知名应用所效仿,如新浪新闻,网易新闻,人人网等 那么这种效果该如何实现呢?那就需要 ...
- openssh升级步骤
1下载openssh最新版本 2 configure ./configure --prefix= /ssh先配置一下 再在本地安装. make &makeinstall 3 按照/ssh包含内 ...