【BZOJ2007】【Noi2010】海拔 平面图最小割转最短路

#include <stdio.h>
int main()
{
	puts("转载请注明出处谢谢");
	puts("http://blog.csdn.net/vmurder/article/details/43280891");
}

题解:这个模型很水,不需要极角序神马转对偶图,直接乱搞就行。

然后目的是把图割开,那么只需要跑S->T最短路就行。

要做平面图转对偶图不妨去这篇。

【BZOJ2965】保护古迹
平面图转对偶图,暴力,网络流

还有就是某人说堆很快233,我弱弱的优先队列竟然,嘿嘿。

@jiangyuze831

BZOJ
2007 NOI 2010 海拔 平面图最小割->最短路SPFA+pq

代码:

#include <queue>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define N 505
#define P 250100
#define M 1501000
using namespace std;
struct KSD
{
	int v,len,next;
}e[M];
int head[P],cnt;
inline void add(int u,int v,int len)
{
	e[++cnt].v=v;
	e[cnt].len=len;
	e[cnt].next=head[u];
	head[u]=cnt;
}
struct YYC
{
	int f,v;
	bool operator < (const YYC &a)const{return f>a.f;}
	YYC(int _f=0,int _v=0):f(_f),v(_v){}
};
int dist[P],s,t;
priority_queue<YYC>pq;
int spfa()
{
	while(!pq.empty())pq.pop();
	memset(dist,0x3f,sizeof dist);

	int i,u,v;
	pq.push(YYC(dist[s]=0,s));
	while(!pq.empty())
	{
		YYC U=pq.top();pq.pop();
		if(dist[u=U.v]!=U.f)continue;
		for(i=head[u];i;i=e[i].next)
		{
			v=e[i].v;
			if(dist[v]>dist[u]+e[i].len)
			{
				dist[v]=dist[u]+e[i].len;
				pq.push(YYC(dist[v],v));
			}
		}
	}
	return dist[t];
}
int n,id[N][N];
void build()
{
	int i,j,k;
	scanf("%d",&n),s=n*n+1,t=n*n+2;
	for(i=1;i<=n;i++)for(j=1;j<=n;j++)id[i][j]=++cnt;
	for(i=1;i<=n;i++)id[0][i]=id[i][n+1]=s,id[i][0]=id[n+1][i]=t;
		cnt=0;
	for(i=1;i<=n+1;i++)for(j=1;j<=n;j++)
	{
		scanf("%d",&k);
		add(id[i-1][j],id[i][j],k);
	}
	for(i=1;i<=n;i++)for(j=1;j<=n+1;j++)
	{
		scanf("%d",&k);
		add(id[i][j],id[i][j-1],k);
	}
	for(i=1;i<=n+1;i++)for(j=1;j<=n;j++)
	{
		scanf("%d",&k);
		add(id[i][j],id[i-1][j],k);
	}
	for(i=1;i<=n;i++)for(j=1;j<=n+1;j++)
	{
		scanf("%d",&k);
		add(id[i][j-1],id[i][j],k);
	}
}
int main()
{
	freopen("test.in","r",stdin);
	build();
	printf("%d\n",spfa());
	return 0;
}
时间: 2024-10-27 09:42:49

【BZOJ2007】【Noi2010】海拔 平面图最小割转最短路的相关文章

BZOJ 2007 NOI2010 海拔 平面图最小割

题目大意:YT市是一个规划良好的城市,城市被东西向和南北向的主干道划分为n×n个区域.简单起见,可以将YT市看作一个正方形,每一个区域也可看作一个正方形.从而,YT城市中包括(n+1)×(n+1)个交叉路口和2n×(n+1)条双向道路(简称道路),每条双向道路连接主干道上两个相邻的交叉路口.下图为一张YT市的地图(n = 2),城市被划分为2×2个区域,包括3×3个交叉路口和12条双向道路. 小Z作为该市的市长,他根据统计信息得到了每天上班高峰期间YT市每条道路两个方向的人流量,即在高峰期间沿着

Vijos1734 NOI2010 海拔 平面图最小割

建立平面图的对偶图,把最小割转化成最短路问题 Dijkstra算法堆优化 (被输入顺序搞WA了好几次T_T) 1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #include <queue> 5 6 const int maxN=502; 7 const int maxV=maxN*maxN; 8 const int inf=0x3f3f3f3f; 9 10 struct E

[bzoj1001][BeiJing2006]狼抓兔子-题解[平面图最小割转最短路]/[Dinic求最小割]

Description 现在小朋友们最喜欢的"喜羊羊与灰太狼",话说灰太狼抓羊不到,但抓兔子还是比较在行的, 而且现在的兔子还比较笨,它们只有两个窝,现在你做为狼王,面对下面这样一个网格的地形: 左上角点为(1,1),右下角点为(N,M)(上图中N=4,M=5).有以下三种类型的道路 1:(x,y)<==>(x+1,y) 2:(x,y)<==>(x,y+1) 3:(x,y)<==>(x+1,y+1) 道路上的权值表示这条路上最多能够通过的兔子数,道路

【Algorithm】平面图最小割转最短路

杭电上碰巧有几道求最小割的题目,用网络流解超时.通过离散数学中的一些知识可以将平面图最小割转化为最短路径,通过最短路解提高效率.这个转化过程很简单,但是很巧妙,详细内容可以参考<浅析最大最小定理在信息学竞赛中的应用>. 1. [HDU] 3870 Catch the Theves有一个网格拓扑,每条边都表示有$A_{ij}$个小偷,现在希望对其中一条边部署警察,使得小偷不可能偷到右下角的财宝.求至少需要多少个警察?这题是个挺有实际意义的题目,基本思路也很简单.因为题目给定小偷都从左上角出发向右

BZOJ 2007 NOI 2010 海拔 平面图最小割-&gt;最短路SPFA+pq

题目大意:给出一个城市各个道路的双向流量,城市的左上角的高度是0,城市的右下角的高度是1,若人流升高海拔就会消耗体力,问最小需要消耗多少体力. 思路:这道题才是真正的让我见识到了algorithm中的heap的强大. 分析这道题可以发现,一定会有一条分界线,这个分界线左边高度都为0,右边高度都是1,然后找到这条分界点就可以了.明显的最小割.但是数据量巨大,直接跑最大流会T,又是平面图,建立对偶图然后跑最短路,SPFA+pq在BZOJ上可以很快,如果有的OJ卡STL的话可以考虑SPFA+Heap,

HDU3870 Catch the Theves(平面图最小割转最短路)

题目大概说给一个n×n的方格,边有权值,问从求(1,1)到(n,n)的最小割. 点达到了160000个,直接最大流不好.这题的图是平面图,求最小割可以转化成求其对偶图的最短路,来更高效地求解: 首先源点汇点间新加一条边,然后构造其对偶图: 面作为对偶图的点:而源点到汇点之间新加的边划分出来的两个面分别作为对偶图的源点和汇点 如果两个面之间有边则两个面在对偶图对应的点连边,权值为原来的边权:去掉对偶图源点和汇点之间边 这样可以发现,对偶图的源点到汇点的一条路径就对应这原图的源点到汇点的一个割边集,

hdu 3870(平面图最小割转最短路)

Catch the Theves Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 65768/32768 K (Java/Others)Total Submission(s): 1640    Accepted Submission(s): 514 Problem Description A group of thieves is approaching a museum in the country of zjsxzy,now t

UVALive - 3661 Animal Run (平面图+最小割+对偶图+最短路)

题目大意:有很多只小动物要从左上角跑到右下角,给出每条线路所需的人手,问至少需要多少人手,才能将所有动物抓住 解题思路:最小割,就是最小割,但是用最大流处理不了,边太多了 具体可以参考算法合集之<浅析最大最小定理在信息学竞赛中的应用> 知道了这个后,这题估计就可以解了 给出我的建图方式 将每一个小三角形从左往右,从上到下依次编号为1-2-3.. 每行的同一个三角行的编号差就是2 * (m - 1) 如图 #include <cstdio> #include <cstring&

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

题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=2007 题意:给出一个n*n的格子,那么顶点显然有(n+1)*(n+1)个.每两个相邻顶点之间有两条边,这两条边是有向的,边上有权值..左上角为源点,右下角为汇点,求s到t的最小割. 思路:很明显这是一个平面图,将其转化为最 短路.我们将s到t之间连一条边,左下角为新图的源点S,右上角区域为新图的终点T,并且为每个格子编号.由于边是有向的,我们就要分析下这条边应该是哪 个点向哪个点的边.