题目:http://acm.hdu.edu.cn/showproblem.php?pid=2066
题意:中文题
想法: 很明显的最短路径问题,有两种想法。
(1)在输入时先记录输入的最大的城市的编号n。增加一个虚拟的起点0,让它与城镇相连的距离为0,再增加一个虚拟的节点n+1,让它与目的地连接且距离为0,则题目转化为求从0到n+1的最短路问题。
(2)用一个数组存起来与城镇相连的城市,然后每一个都进行一次spfa,求最小值即可。我用这种方法做的。。。貌似没第一种简单= =
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
const int INF=1<<20;
bool vis[1010];
int link[1010][1010],dis[1010];
queue <int> ss;
int t,s,d;
int city[1010],aim[1010];
void init(){
for(int i=1;i<=1010;i++){
for(int j=1;j<=1010;j++){
link[i][j]=link[j][i]=INF;
}
}
}
void spfa(int st){
while(!ss.empty()) ss.pop();
for(int i=1;i<=1010;i++)
dis[i]=INF;
dis[st]=0;
memset(vis,false,sizeof(vis));
vis[st]=true;
ss.push(st);
while(!ss.empty()){
int x=ss.front();
ss.pop();
vis[x]=false;
for(int i=1;i<=1010;i++){
if(dis[i]>dis[x]+link[x][i]){
dis[i]=dis[x]+link[x][i];
if(!vis[i]){
vis[i]=true;
ss.push(i);
}
}
}
}
}
int main(){
while(~scanf("%d%d%d",&t,&s,&d)){
init();
for(int i=0;i<t;i++){
int a,b,time;
cin>>a>>b>>time;
if(link[a][b]>time){
link[a][b]=link[b][a]=time;
}
}
memset(city,0,sizeof(city));
for(int i=0;i<s;i++){
cin>>city[i];
}
for(int i=0;i<d;i++){
cin>>aim[i];
}
int ans=INF;
for(int i=0;i<s;i++){
spfa(city[i]);
for(int i=0;i<d;i++){
ans=min(ans,dis[aim[i]]);
}
}
cout<<ans<<endl;
}
return 0;
}