题目大意:给出一个地图,如果经过两个不同的区块,需要花费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:
时间: 2024-10-12 19:20:27