[题目链接]
感想:
本来不想搞事情哒,自己写的优先队列也很快了,但是看到ranking里大佬40ms+的代码,总是忍不住瞅一瞅,直到看某童鞋的函数名为spfa,再看看自己的代码,幡然醒悟自己写的也不过是个最短路,随决定优化一波~~
解法1:
Spfa大法好呀~(50ms+)
#include<iostream>
#include<cstdio>
#include<vector>
#include<queue>
#include<cstring>
#include<algorithm>
using namespace std;
typedef pair<int,int>P;
const int inf=0x3f3f3f3f;
const int Max_n=330;
int n,m,q;
char s[Max_n][Max_n];
int dx[4]={0,0,-1,1};
int dy[4]={-1,1,0,0};
bool vis[Max_n][Max_n];
int dist[Max_n][Max_n];
vector<P>G[Max_n][Max_n];
void Spfa(int sx,int sy){
queue<P>que;
que.push(P(sx,sy));
dist[sx][sy]=0;vis[sx][sy]=1;
while(!que.empty()){
P p=que.front();que.pop();
int x=p.first,y=p.second;
vis[x][y]=0;
for(int i=0;i<4;i++){ //上下左右
int X=x+dx[i];
int Y=y+dy[i];
if((s[X][Y]=='.'||s[X][Y]=='T')&&dist[x][y]+1<dist[X][Y]){
dist[X][Y]=dist[x][y]+1;
if(!vis[X][Y]){
vis[X][Y]=1;
que.push(P(X,Y));
}
}
}
for(int i=0;i<G[x][y].size();i++){ // 传送门
int X=G[x][y][i].first;
int Y=G[x][y][i].second;
if((s[X][Y]=='.'||s[X][Y]=='T')&&dist[x][y]+3<dist[X][Y]){
dist[X][Y]=dist[x][y]+3;
if(!vis[X][Y]){
vis[X][Y]=1;
que.push(P(X,Y));
}
}
}
}
}
int main()
{
while(~scanf("%d%d%d",&n,&m,&q)){
memset(s,0,sizeof(s));
memset(dist,0x3f,sizeof(dist));
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++)
G[i][j].clear();
}
for(int i=1;i<=n;i++)scanf("%s",s[i]+1);
int sx,sy,tx,ty;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
if(s[i][j]=='S'){sx=i;sy=j;}
if(s[i][j]=='T'){tx=i;ty=j;}
}
}
int a,b,c,d;
for(int i=0;i<q;i++){
scanf("%d%d%d%d",&a,&b,&c,&d);
G[a+1][b+1].push_back(P(c+1,d+1));
}
Spfa(sx,sy);
if(dist[tx][ty]<inf)printf("%d\n",dist[tx][ty]);
else printf("-1\n");
}
return 0;
}
解法2:
Dijkstra只能说稳~(80ms+)
#include<iostream>
#include<cstdio>
#include<vector>
#include<queue>
#include<cstring>
#include<algorithm>
using namespace std;
const int Max_n=330;
int n,m,q;
struct edge{
int x,y,d;
edge(int xx,int yy,int dd):x(xx),y(yy),d(dd){}
bool operator<(const edge& e)const{
return d>e.d;
}
};
char s[Max_n][Max_n];
int dist[Max_n][Max_n];
int dx[4]={0,0,-1,1};
int dy[4]={-1,1,0,0};
vector<edge>G[Max_n][Max_n];
int Dijkstra(int sx,int sy){
priority_queue<edge>que;
que.push(edge(sx,sy,0));
dist[sx][sy]=0;
while(!que.empty()){
edge e=que.top();que.pop();
if(s[e.x][e.y]=='T')return e.d;
if(e.d>dist[e.x][e.y])continue;
for(int i=0;i<4;i++){
int X=e.x+dx[i];
int Y=e.y+dy[i];
if((s[X][Y]=='.'||s[X][Y]=='T')&&e.d+1<dist[X][Y]){
dist[X][Y]=e.d+1;
que.push(edge(X,Y,e.d+1));
}
}
for(int i=0;i<G[e.x][e.y].size();i++){
int X=G[e.x][e.y][i].x;
int Y=G[e.x][e.y][i].y;
if((s[X][Y]=='.'||s[X][Y]=='T')&&e.d+3<dist[X][Y]){
dist[X][Y]=e.d+3;
que.push(edge(X,Y,e.d+3));
}
}
}
return -1;
}
int main()
{
while(~scanf("%d%d%d",&n,&m,&q)){
memset(dist,0x3f,sizeof(dist));
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++)
G[i][j].clear();
}
for(int i=1;i<=n;i++)scanf("%s",s[i]+1);
int sx,sy;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++)
if(s[i][j]=='S'){sx=i;sy=j;}
}
int a,b,c,d;
for(int i=0;i<q;i++){
scanf("%d%d%d%d",&a,&b,&c,&d);
G[a+1][b+1].push_back(edge(c+1,d+1,0));
}
printf("%d\n",Dijkstra(sx,sy));
}
return 0;
}