sicily 1889. Max’s game

// 题意: 有n*m矩阵,从起点(sx,sy)出发,可以上下左右四个方向移动,
// 若两个位置上是相同字符,则花费为0,否则为1,求到终点的最短距离
// 用Dijkstra算法解决,但会 TLE ,需要用 优先队列 优化时间

#include <iostream> // 邻接矩阵+优先队列实现Dijkstra算法
#include <stdio.h>

#include <queue>
#include <cstring>
using namespace std;
const int INF=300000;
const int MAXN=250000;
int n,m,distD[MAXN],done[MAXN];
int sx,sy,tx,ty; //起点(sx,sy)和终点(tx,ty)
int dx[4]={0,0,1,-1},dy[4]={1,-1,0,0};

char data[500][500];
typedef pair<int,int> pii;

void Dijkstra(int st) //从源点st到其余各顶点的最短路径长度
{

priority_queue<pii, vector<pii>, greater<pii> > q;
fill(distD,distD+n*m,INF); //结点下标从0开始,共有 m * n 个结点
distD[st]=0;

fill(done,done+n*m,0);
q.push(make_pair(distD[st], st));
while(!q.empty())
{
pii u = q.top();
q.pop();
int p = u.second;
if(done[p])
continue;
done[p] = 1;
if( p == tx * m + ty ) // 如果探测到终点即可退出
{

printf("%d\n",distD[p]);
break;
}
for(int d=0;d<4;++d)
{
int newx=p/m+dx[d],newy=p%m+dy[d];
int newp=newx*m+newy;
if(newx>=0&&newx<n&&newy>=0&&newy<m&& !done[newp] )
{
int w = ( data[p/m][p%m] == data[newx][newy] ) ? 0 : 1 ;
if( distD[p] + w < distD[newp] )
{
distD[newp]=distD[p]+w;
q.push(make_pair(distD[newp], newp));
}
}
}
}
}
int main()
{
while(scanf("%d%d",&n,&m)!=EOF) // n 行 m 列
{

for(int i=0;i<n;++i)
{
scanf("%s",data[i]);
}
scanf("%d%d%d%d",&sx,&sy,&tx,&ty);
Dijkstra(sx*m+sy); // 顶点坐标[x,y],则在队列对应的下标是 x * m + y
}

return 0;
}

posted on 2011-07-17 14:49  sysu_mjc  阅读(210)  评论(1编辑  收藏  举报

导航