L3-007. 天梯地图
题目链接:https://www.patest.cn/contests/gplt/L3-007
Dijstra
这题是Dijstra的变形,麻烦的是两种最短路的相同距离时的选择条件不同,也就是说要写两个Dijstra函数。很早就写完了代码,不过debug了一星期,最后还是参考他人博客才知道自己错哪了= =(易错点已注释)
代码如下:
#include<cstdio>
#include<cstring>
#include<stack>
#define N 505
using namespace std;
const int INF=0x3f3f3f3f;
bool mark[N];
int n,Start,End;
int lenmp[N][N];
int timemp[N][N];
int lendis[N];
int timedis[N];
int lenpre[N];
int timepre[N];
void lenDijstra();
void timeDijstra();
int main(void){
/**输入**/
memset(lenpre,-,sizeof(lenpre));
memset(timepre,-,sizeof(timepre));
int m;
scanf("%d%d",&n,&m);
for(int i=;i<n;++i){
lendis[i]=INF;
timedis[i]=INF;
for(int j=;j<n;++j){
lenmp[i][j]=INF;
timemp[i][j]=INF;
}
}
while(m--){
int a,b,one,length,time;
scanf("%d%d%d%d%d",&a,&b,&one,&length,&time);
if(one){
lenmp[a][b]=length;
timemp[a][b]=time;
}else{
lenmp[a][b]=lenmp[b][a]=length;
timemp[a][b]=timemp[b][a]=time;
}
}
scanf("%d%d",&Start,&End);
/**数据处理**/
lenDijstra();
timeDijstra();
/**输出**/
int k=End;
bool flag=;
stack<int>times;
while(k!=Start){
times.push(k);
if(timepre[k]!=lenpre[k])flag=;
k=timepre[k];
}
if(flag){
printf("Time = %d;",timedis[End]);
printf(" Distance = %d:",lendis[End]);
printf("% d",Start);
while(!times.empty()){
printf(" => %d",times.top());
times.pop();
}
printf("\n");
}else{
printf("Time = %d:",timedis[End]);
printf("% d",Start);
while(!times.empty()){
printf(" => %d",times.top());
times.pop();
}
printf("\n");
printf("Distance = %d:",lendis[End]);
printf("% d",Start);
stack<int>diss;
k=End;
while(k!=Start){
diss.push(k);
k=lenpre[k];
}
while(!diss.empty()){
printf(" => %d",diss.top());
diss.pop();
}
printf("\n");
}
return ;
}
void lenDijstra(){
int node[N];
memset(node,,sizeof(node));
node[Start]=; memset(mark,,sizeof(mark));
lendis[Start]=;
while(){
int Min=INF,index;
for(int i=;i<n;++i){
if(mark[i]&&Min>lendis[i]){
Min=lendis[i];
index=i;
}
}
if(Min==INF)break;
mark[index]=;
for(int i=;i<n;++i){
int d=lendis[index]+lenmp[index][i];
if(mark[i]&&lendis[i]>d){
lendis[i]=d;
lenpre[i]=index;
node[i]=node[index]+; /*非node[i]++*/
}else if(mark[i]&&lendis[i]==d&&node[index]+<node[i]){
lenpre[i]=index;
node[i]=node[index]+;
}
}
}
}
void timeDijstra(){
memset(mark,,sizeof(mark));
int dis[N];
for(int i=;i<n;++i)
dis[i]=lenmp[Start][i];
timedis[Start]=;
dis[Start]=;
while(){
int Min=INF,index;
for(int i=;i<n;++i){
if(mark[i]&&Min>timedis[i]){
Min=timedis[i];
index=i;
}
}
if(Min==INF)break;
mark[index]=;
for(int i=;i<n;++i){
int t=timedis[index]+timemp[index][i];
int d=dis[index]+lenmp[index][i];
if(mark[i]&&timedis[i]>t){
dis[i]=d;
timedis[i]=t;
timepre[i]=index;
}else if(mark[i]&&timedis[i]==t&&dis[i]>d){
dis[i]=d;
timepre[i]=index;
}
}
}
}