这个题有两点需要注意,第一是可能两个车站之间有多条路径,第二是起点可能有多个。这个题可以逆向思考,将起点作为终点来做,输入路径的时候将起点和终点反过来输入。还有一种很巧妙的办法就是加超级源点,将其他几个源点都连到它上边,距离都为零。
#include<stdio.h>
#include<iostream>
#include<queue>
#include<string.h>
#include<algorithm>
using namespace std;
const int MAX=999999999;
const int edge_max=21000;
const int point_max=1100;
struct node
{
int en;
int lenth;
int next;
} edge[edge_max];
int pos_in_edge[point_max],Star;
int dis[point_max],n,m,en_num,en_po[1100];
bool vis[point_max];
queue<int>Q;
void init()
{
memset(pos_in_edge,-1,sizeof(pos_in_edge));
int positn=1,sta,enb,lenc;
for(int i=0; i<m; i++)
{
cin>>enb>>sta>>lenc;
edge[positn].en=enb;
edge[positn].lenth=lenc;
edge[positn].next=pos_in_edge[sta];
pos_in_edge[sta]=positn++;
}
cin>>en_num;
for(int i=0; i<en_num; i++)
{
cin>>en_po[i]; //cout<<en_po[i]<<endl;
}
}
void SPFA()
{
memset(vis,0,sizeof(vis));
fill(dis,dis+point_max,MAX);
dis[Star]=0;
vis[Star]=true;
Q.push(Star);
while(!Q.empty())
{
int e_st_p=Q.front();
vis[e_st_p]=false;
Q.pop();
for(int j=pos_in_edge[e_st_p]; j!=-1; j=edge[j].next)
{
int e_en_p=edge[j].en;
if(dis[e_en_p]>edge[j].lenth+dis[e_st_p])
{
dis[e_en_p]=edge[j].lenth+dis[e_st_p];
if(!vis[e_en_p])
{
Q.push(e_en_p);
vis[e_en_p]=true;
}
}
}
}
int ans=MAX;
for(int i=0; i<en_num; i++)
if(ans>dis[en_po[i]])
ans=dis[en_po[i]];
if(ans==MAX)
cout<<-1<<endl;
else
cout<<ans<<endl;
}
int main()
{
while(scanf("%d%d%d",&n,&m,&Star)!=EOF&&(n+m)!=0)
{
init();
SPFA();
}
return 0;
}