首页 > 代码库 > 【BZOJ2464】【中山市选2009】小明的游戏 最短路水过

【BZOJ2464】【中山市选2009】小明的游戏 最短路水过

题解:最短路pqspfa200ms,一眼题,


另一种想出来没写的做法:二分答案,上界n+m

时间复杂度O(n*m*log(n+m)),二分+深搜看能不能找到t


最短路代码:

#include <queue>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define N 505
#define NN 251000
#define inf 0x3f3f3f3f
using namespace std;
const int dx[]={0,0,1,-1};
const int dy[]={1,-1,0,0};
struct KSD
{
	int v,len,next;
}e[NN<<2];
int head[NN],cnt;
void add(int u,int v,int len)
{
	++cnt;
	e[cnt].v=v;
	e[cnt].len=len;
	e[cnt].next=head[u];
	head[u]=cnt;
}
int dist[NN],in[NN];
struct Vayne
{
	int f,v;
	bool operator < (const Vayne &a)const
	{return f>a.f;}
	Vayne(){}
	Vayne(int _f,int _v):f(_f),v(_v){}
};
int s,t,n,m,id[N][N],num;
char map[N][N];
priority_queue<Vayne>q;
void init()
{
	num=cnt=0;
	memset(head,0,sizeof(head));
}
int spfa()
{
	while(!q.empty())q.pop();
	memset(dist,0x3f,sizeof(dist));
	memset(in,0,sizeof(in));
	int i,u,v,temp;
	dist[s]=0;
	in[s]=1;
	q.push(Vayne(0,s));
	while(!q.empty())
	{
		Vayne U=q.top();q.pop();
		u=U.v;
		in[u]=0;
		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;
				if(!in[v])
				{
					in[v]=1;
					q.push(Vayne(dist[v],v));
				}
			}
		}
	}
	return dist[t];
}
bool build()
{
	int i,j,k;
	int a,b,c;
	int x,y;
	init();
	scanf("%d%d",&n,&m);
	if(n==0&&m==0)return 0;
	for(i=1;i<=n;i++)scanf("%s",map[i]+1);
	for(i=1;i<=n;i++)for(j=1;j<=m;j++)id[i][j]=++num;
	for(i=1;i<=n;i++)for(j=1;j<=m;j++)
	{
		int iid=id[i][j];
		for(k=0;k<4;k++)
		{
			x=i+dx[k];
			y=j+dy[k];
			if(id[x][y])
			{
				int len=(map[i][j]==map[x][y]);
				add(iid,id[x][y],!len);
				add(id[x][y],iid,!len);
			}
		}
	}
	scanf("%d%d%d%d",&a,&b,&x,&y);
	s=id[a+1][b+1];
	t=id[x+1][y+1];
	return 1;
}
int main()
{
//	freopen("test.in","r",stdin);
	while(build())printf("%d\n",spfa());
	return 0;
}


【BZOJ2464】【中山市选2009】小明的游戏 最短路水过