思路:最短路
分析:只要把名字映射成整数,然后利用整数去求解即可。
注意事项:
1 题目中的起点和终点可能相同,这个时候输出0。
2 用map映射的时候用char类型,由于string是个类效率比较低。
3 处理成无向图
代码:
/*SPFA*/
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<string>
#include<cstring>
#include<queue>
#include<map>
using namespace std;
#define MAXN 20010
#define INF 0XFFFFFFF
int n , cnt;
int begin , goal;
int first[MAXN] , next[MAXN];
int star[MAXN] , end[MAXN] , value[MAXN];
int dis[MAXN];
queue<int>q;
map<string , int>m;
void init(){
cnt = 0;
m.clear();
for(int i = 1 ; i <= 200 ; i++){
first[i] = -1;
next[i] = -1;
}
}
void SPFA(int s){
while(!q.empty())
q.pop();
int vis[MAXN];
memset(vis , 0 , sizeof(vis));
for(int i = 1 ; i <= cnt ; i++)
dis[i] = INF;
dis[s] = 0;
q.push(s);
vis[s] = 1;
while(!q.empty()){
int x = q.front();
q.pop();
vis[x] = 0;
for(int i = first[x] ; i != -1 ; i = next[i]){
if(dis[end[i]] > dis[x] + value[i]){
dis[end[i]] = dis[x] + value[i];
if(!vis[end[i]]){
vis[end[i]] = 1;
q.push(end[i]);
}
}
}
}
}
void input(){
int a , b , v;
char str1[200] , str2[200];
init();
scanf("%s%s" , str1 , str2);
/*这里判断是不是相同点*/
a = m[str1];
if(!a)
m[str1] = a = ++cnt;
b = m[str2];
if(!b)
m[str2] = b = ++cnt;
begin = a;
goal = b;
for(int i = 0 ; i < n ; i++){
scanf("%s%s%d" , str1 , str2 , &v);
a = m[str1];
if(!a)
m[str1] = a = ++cnt;
b = m[str2];
if(!b)
m[str2] = b = ++cnt;
/*处理成无向图*/
star[i] = a;
end[i] = b;
value[i] = v;
star[i+n] = b;
end[i+n] = a;
value[i+n] = v;
next[i] = first[star[i]];
first[star[i]] = i;
next[i+n] = first[star[i+n]];
first[star[i+n]] = i+n;
}
}
int main(){
while(scanf("%d" , &n) && n != -1){
input();
SPFA(begin);
if(dis[goal] != INF)
printf("%d\n" , dis[goal]);
else
printf("-1\n");
}
return 0;
}
/*floyd*/
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<string>
#include<cstring>
#include<queue>
#include<map>
using namespace std;
#define MAXN 200
#define INF 0xFFFFFFF
int n , star , end , cnt;
long long dis[MAXN][MAXN];
map<string , int>m;
long long min(long long a , long long b){
return a < b ? a : b;
}
void init(){
cnt = 0;
m.clear();
for(int i = 1 ; i < MAXN ; i++){
for(int j = 1 ; j < MAXN ; j++){
if(i == j)
dis[i][j] = 0;
else
dis[i][j] = INF;
}
}
}
void floyd(){
for(int k = 1 ; k <= cnt ; k++){
for(int i = 1 ; i <= cnt ; i++){
for(int j = 1 ; j <= cnt ; j++)
dis[i][j] = min(dis[i][k]+dis[k][j] , dis[i][j]);
}
}
}
void input(){
int a , b , v;
char str1[MAXN] , str2[MAXN];
init();
scanf("%s%s" , str1 , str2);
a = m[str1];
if(!a)
m[str1] = a = ++cnt;
b = m[str2];
if(!b)
m[str2] = b = ++cnt;
star = a;
end = b;
for(int i = 0 ; i < n ; i++){
scanf("%s%s%d" , str1 , str2 , &v);
a = m[str1];
b = m[str2];
if(!a)
m[str1] = a = ++cnt;
if(!b)
m[str2] = b = ++cnt;
if(dis[a][b] > v)
dis[a][b] = dis[b][a] = v;
}
}
int main(){
while(scanf("%d" , &n) && n != -1){
input();
floyd();
if(dis[star][end] != INF)
printf("%d\n" , dis[star][end]);
else
printf("-1\n");
}
return 0;
}