首页 > 代码库 > BZOJ 2464 中山市选 2009 小明的游戏 最短路

BZOJ 2464 中山市选 2009 小明的游戏 最短路

题目大意:给出一个地图,如果经过两个不同的区块,需要花费1,否则不需要花费。问从st到ed最小需要花费多少。


思路:签到题。


#include <queue>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define MAX 510
#define MAXP 250010
#define MAXE 2000010
using namespace std;
const int dx[] = {0,1,-1,0,0};
const int dy[] = {0,0,0,1,-1};

struct Status{
	int pos,len;
	
	Status(int _,int __):pos(_),len(__) {}
	bool operator <(const Status &a)const {
		return len > a.len;
	}
};

char src[MAX][MAX];
int num[MAX][MAX];
int head[MAXP],total;
int next[MAXE],aim[MAXE],length[MAXE];

int st,ed,m,n;
int f[MAXP];

inline void Initialize()
{
	total = 0;
	memset(head,0,sizeof(head));
}

inline void Add(int x,int y,int len)
{
	next[++total] = head[x];
	aim[total] = y;
	length[total] = len;
	head[x] = total;
}

inline int SPFA()
{
	static priority_queue<Status> q;
	while(!q.empty())	q.pop();
	memset(f,0x3f,sizeof(f));
	q.push(Status(st,0));
	f[st] = 0;
	while(!q.empty()) {
		Status now = q.top(); q.pop();
		if(f[now.pos] < now.len)	continue;
		int x = now.pos;
		for(int i = head[x]; i; i = next[i])
			if(f[aim[i]] > f[x] + length[i]) {
				f[aim[i]] = f[x] + length[i];
				q.push(Status(aim[i],f[aim[i]]));
			}
	}
	return f[ed];
}

int main()
{
	while(scanf("%d%d",&m,&n),m + n) {
		Initialize();
		for(int i = 1; i <= m; ++i)
			scanf("%s",src[i] + 1);
		int cnt = 0;
		for(int i = 1; i <= m; ++i)
			for(int j = 1; j <= n; ++j)
				num[i][j] = ++cnt;
		int x,y;
		scanf("%d%d",&x,&y);
		x++,y++,st = num[x][y];
		scanf("%d%d",&x,&y);
		x++,y++,ed = num[x][y];
		for(int i = 1; i <= m; ++i)
			for(int j = 1; j <= n; ++j)
				for(int k = 1; k <= 4; ++k) {
					int fx = i + dx[k];
					int fy = j + dy[k];
					if(!fx * fy || fx > m || fy > n)	continue;
					Add(num[i][j],num[fx][fy],src[fx][fy] != src[i][j]);
				}
		printf("%d\n",SPFA());
	}
	return 0;
}


CODE:


BZOJ 2464 中山市选 2009 小明的游戏 最短路