题目大意:给定公交车的起始站以及时间情况,问从起点到终点最短花费时间是多少?
解题思路:该题是简单的Dijkstra运用,主要在于对站台名为字符串的处理。这里可以利用STL中的map进行站台名和一一对应的数字进行映射处理,这样的处理使得该题直接拍一个Dijkstra就完成了,但运行时间有点高,应该可以继续优化下。详见code.
题目来源:http://acm.hdu.edu.cn/showproblem.php?pid=2112
code:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <map>
using namespace std;
const int MAXN = 150;
const int N = 35;
const int INF = 99999999;
int vis[MAXN],dist[MAXN],state[MAXN][MAXN];
int T,s,e,c;
char st[N],en[N],a[N],b[N];
void init(){ //初始化
for(int i=0;i<MAXN;i++)
for(int j=0;j<MAXN;j++){
if(i==j) state[i][j]=0;
else state[i][j]=state[j][i]=INF;
}
}
void Dijkstra(int s,int e){
memset(vis,0,sizeof(vis)); //初始化访问标记
for(int i=s;i<=e;i++) dist[i]=(i==s ? 0 : INF); //初始化dist数组
for(int i=s;i<=e;i++){
int pos,min=INF;
for(int j=s;j<=e;j++) //找出未标记点中的最小值
if(!vis[j] && min>dist[j]) min=dist[pos=j];
vis[pos]=1; //标记pos
for(int k=s;k<=e;k++) //更新dist数组
if(dist[k]>dist[pos]+state[pos][k])
dist[k]=dist[pos]+state[pos][k];
}
}
int main(){
map<string,int> arr;
while(scanf("%d",&T)!=EOF && (T!=-1)){
arr.clear(); //map初始化
init(); //图的初始化
int flag=0;
scanf("%s%s",&st,&en);
if(strcmp(st,en)==0) flag = 1; //起点和终点相等则标记,输出0
arr[st]=1;arr[en]=2; //起点和终点分别标记为1、2;
int tmp=3;
while(T--){
scanf("%s%s%d",&a,&b,&c);
if(!arr[a]) arr[a]=tmp++; //map中不存在该键,则值存为tmp++
if(!arr[b]) arr[b]=tmp++;
if(c<state[arr[a]][arr[b]]) //接收权值
state[arr[a]][arr[b]]=state[arr[b]][arr[a]]=c;
}
if(flag){
printf("0\n");
continue;
}
Dijkstra(1,tmp);
if(dist[2]<INF) printf("%d\n",dist[2]);
else printf("-1\n");
}
return 0;
}