码迷,mamicode.com
首页 > 其他好文 > 详细

BZOJ 1967 Ahoi2005 CROSS 穿越磁场 FloodFill+BFS

时间:2015-02-24 09:06:10      阅读:163      评论:0      收藏:0      [点我收藏+]

标签:bzoj   bzoj1967   floodfill   bfs   

题目大意:给定平面上的n个正方形,求某个点到另一个点至少穿过多少个边界

一开始想对于每个正方形判断一下起点和终点是否在同一侧= = 但是反例显然

考虑到n<=100,可以离散化一下,然后用Floodfill标记每块区域

然后跑最短路就行了……由于边权都是1,所以用BFS就能搞出最短路了

连边连挂了调了半宿……

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define M 310
using namespace std;
struct abcd{
	int x,y,c;
	friend istream& operator >> (istream &_,abcd &a)
	{
		scanf("%d%d%d",&a.x,&a.y,&a.c);
		return _;
	}
}a[M];
struct Rectangle{
	int x1,x2,y1,y2;
}rectangles[M];
struct edge{
	int to,next;
}table[500500];
int head[M*M],tot;
int m=1,n=1,cnt,T;
int xa,ya,xb,yb,map[M][M],f[100100];
pair<int,int*> b[M];
bool map1[M][M],map2[M][M];
void Add(int x,int y)
{
	table[++tot].to=y;
	table[tot].next=head[x];
	head[x]=tot;
}
void Floodfill(int x,int y)
{
	
	int xx,yy;
	
	map[x][y]=T;

	xx=x,yy=y-1;
	if( !map1[x][y] )
	{
		if( y!=1 && !map[xx][yy] )
			Floodfill(xx,yy);
	}
	else if(map[xx][yy])
		Add(T,map[xx][yy]),Add(map[xx][yy],T);
		
	xx=x,yy=y+1;
	if( !map1[x][y+1] )
	{
		if( y!=n && !map[xx][yy] )
			Floodfill(xx,yy);
	}
	else if(map[xx][yy])
		Add(T,map[xx][yy]),Add(map[xx][yy],T);
		
	xx=x-1,yy=y;
	if( !map2[x][y] )
	{
		if( x!=1 && !map[xx][yy] )
			Floodfill(xx,yy);
	}
	else if(map[xx][yy])
		Add(T,map[xx][yy]),Add(map[xx][yy],T);
		
	xx=x+1,yy=y;
	if( !map2[x+1][y] )
	{
		if( x!=m && !map[xx][yy] )
			Floodfill(xx,yy);
	}
	else if(map[xx][yy])
		Add(T,map[xx][yy]),Add(map[xx][yy],T);

	
}
void BFS()
{
	static int q[65540];
	static unsigned short r,h;
	int i;
	f[q[++r]=map[xa][ya]]=1;
	while(r!=h)
	{
		int x=q[++h];
		for(i=head[x];i;i=table[i].next)
			if(!f[table[i].to])
				f[q[++r]=table[i].to]=f[x]+1;
	}
}
int main()
{
	int i,j;
	cin>>cnt;
	for(i=1;i<=cnt;i++)
		cin>>a[i];
	cin>>xa>>ya>>xb>>yb;

	for(i=1;i<=cnt;i++)
	{
		b[i+i-1]=make_pair(a[i].x,&rectangles[i].x1);
		b[i<<1]=make_pair(a[i].x+a[i].c,&rectangles[i].x2);
	}
	b[cnt<<1|1]=make_pair(xa,&xa);
	b[cnt+1<<1]=make_pair(xb,&xb);
	sort(b+1,b+(cnt+1<<1)+1);
	for(i=1;i<=(cnt+1<<1);i++)
	{
		if(i==1||b[i].first!=b[i-1].first)
			++m;
		*b[i].second=m;
	}
	m+=2;

	for(i=1;i<=cnt;i++)
	{
		b[i+i-1]=make_pair(a[i].y,&rectangles[i].y1);
		b[i<<1]=make_pair(a[i].y+a[i].c,&rectangles[i].y2);
	}
	b[cnt<<1|1]=make_pair(ya,&ya);
	b[cnt+1<<1]=make_pair(yb,&yb);
	sort(b+1,b+(cnt+1<<1)+1);
	for(i=1;i<=(cnt+1<<1);i++)
	{
		if(i==1||b[i].first!=b[i-1].first)
			++n;
		*b[i].second=n;
	}
	n+=2;

	for(i=1;i<=cnt;i++)
	{
		for(j=rectangles[i].x1;j<rectangles[i].x2;j++)
			map1[j][rectangles[i].y1]=map1[j][rectangles[i].y2]=true;
		for(j=rectangles[i].y1;j<rectangles[i].y2;j++)
			map2[rectangles[i].x1][j]=map2[rectangles[i].x2][j]=true;
	}

	for(i=1;i<=m;i++)
		for(j=1;j<=n;j++)
			if(!map[i][j])
				++T,Floodfill(i,j);

	BFS();
	cout<<f[map[xb][yb]]-1<<endl;
	return 0;
}


BZOJ 1967 Ahoi2005 CROSS 穿越磁场 FloodFill+BFS

标签:bzoj   bzoj1967   floodfill   bfs   

原文地址:http://blog.csdn.net/popoqqq/article/details/43922347

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!