/* 题目大意: 给你一个有向图,一个起点集合,一个终点,求最短路。。。。 解题思路: 1.自己多加一个超级源点,把起点集合连接到超级源点上, 然后将起点与超级源点的集合的路径长度设为0,这样就称为一个n+1个点的单源最短路算法。。。。。 2.反向图+终点的Dijkstra,然后记录最小值。 */ #include<iostream> #include<cstdio> #include<cstring> #include<queue> #include<algorithm> using namespace std; const int maxn=1002; const int INF=1<<29; int map[maxn][maxn],n,m,e,dis[maxn],vis[maxn]; struct Node { int v,next,w; bool operator < (const Node &a) const { return w > a.w; } } Edge[2000002],t1,t2; int dijstra(int st,int ed) { priority_queue<Node>q; memset(vis,0,sizeof(vis)); for(int i=0; i<=n; i++) { dis[i]=INF; if(map[st][i]<dis[i]) { dis[i] = map[st][i]; t1.w = dis[i]; t1.v = i; q.push(t1); } } dis[st]=0;//此句没加错了2次,囧~~~ vis[st] = 1; while(!q.empty()) { t1 = q.top(); q.pop(); int u = t1.v; if(vis[u]) continue; vis[u] = 1; for(int v=0; v<=n; v++) { if(!vis[v]) { if(dis[v]>dis[u]+map[u][v]) { dis[v] =dis[u]+map[u][v]; t2.v = v; t2.w = dis[v]; q.push(t2); } } } } if(dis[ed]>=INF)return -1; return dis[ed]; } int main() { while(scanf("%d%d%d",&n,&m,&e)!=EOF) { int i,j,s,a,b,w,ans=1<<29; for(i=0;i<=n;i++) { for(j=0;j<=n;j++) { map[i][j]=INF; } map[i][i]=0; } for(i=1;i<=m;i++) { scanf("%d%d%d",&a,&b,&w); map[a][b]=min(map[a][b],w); } scanf("%d",&w); for(i=1;i<=w;i++) { scanf("%d",&s); map[0][s]=0; } printf("%d\n",dijstra(0,e)); } return 0; }