//题意是很明显的最短路径(注意是有向图),但是用floyd会超时,用dijkstra //这里有个小技巧,就是用逆向思维,将终点视为起点,这样只要用一次dijkstra //然后找出最小值就可以了,当然保存路劲的时候也要逆向。 #include<iostream> using namespace std; const int Max=INT_MAX/2; const int N=1001; int mat[N][N]; bool visited[N]; int dist[N]; int n,m,s,w; int Minval(int n) { int next=-1; for(int i=0;i<n;i++) //因为起点不固定,所以这里要从0开始找 { if(!visited[i]&&(next==-1||dist[i]<dist[next])) next=i; } return next; } void dijkstra(int n) { int i,j; for(i=0;i<n;i++) {dist[i]=mat[s-1][i];} //这里设置起点,我是从0开始编号的 fill(visited,visited+n,false); visited[s-1]=true; for(j=1;j<n;j++) { int next=Minval(n); visited[next]=true; for (int i=0;i<n;i++) { if (dist[i]>dist[next]+mat[next][i]) dist[i]=dist[next]+mat[next][i]; } } } int main() { while(scanf("%d%d%d",&n,&m,&s)!=EOF) { int i; int st,ed,len; fill(&mat[0][0],&mat[n-1][n-1]+1,Max); for(i=0;i<n;i++) mat[i][i]=0; for(i=0;i<m;i++) { scanf("%d%d%d",&st,&ed,&len); st--;ed--; if(len<mat[ed][st]) //取重复数据中最小的len { mat[ed][st]=len; //这里是逆向的! } } dijkstra(n); int ans=INT_MAX; scanf("%d",&w); for(i=0;i<w;i++) { int t; scanf("%d",&t); t--; if(dist[t]<ans) ans=dist[t]; //找出最小值即可 } //for(i=0;i<n;i++) cout<<dist[i]<<endl; if(ans==Max) printf("-1/n"); else printf("%d/n",ans); } return 0; }