TonyY是一个喜欢到处浪的男人,他的梦想是带着兰兰姐姐浪遍天朝的各个角落,不过在此之前,他需要做好规划。
现在他的手上有一份天朝地图,上面有n个城市,m条交通路径,每条交通路径都是单行道。他已经预先规划好了一些点作为旅游的起点和终点,他想选择其中一个起点和一个终点,并找出从起点到终点的一条路线亲身体验浪的过程。但是他时间有限,所以想选择耗时最小的,你能告诉他最小的耗时是多少吗?
Input
包含多组测试数据。
输入第一行包括两个整数n和m,表示有n个地点,m条可行路径。点的编号为1 - n。
接下来m行每行包括三个整数i, j, cost,表示从地点i到地点j需要耗时cost。
接下来一行第一个数为S,表示可能的起点数,之后S个数,表示可能的起点。
接下来一行第一个数为E,表示可能的终点数,之后E个数,表示可能的终点。
0<S, E≤n≤100000,0<m≤100000,0<cost≤100。
Output
输出他需要的最短耗时。
Sample Input
4 4 1 3 1 1 4 2 2 3 3 2 4 4 2 1 2 2 3 4
Sample Output
1
em 这个题开始就想到了炒鸡源点和炒鸡汇点,结果偷懒不写队列优化T了,看到网上很多用spfa的,还有用网络流的大佬,网络流我还不会,这里附上队列优化迪杰斯特拉的解法
1 #include<iostream> 2 #include<cstdio> 3 #include<vector> 4 #include<string.h> 5 #include<queue> 6 #include<utility> 7 #define INF 0x3f3f3f3f 8 9 using namespace std; 10 typedef pair<int,int> P; 11 12 struct node 13 { 14 int to,w; 15 node(int v,int val):to(v),w(val) {} 16 }; 17 18 int n,m; 19 const int maxn = 100007; 20 int vis[maxn]; 21 int dist[maxn]; 22 vector<node>g[maxn]; 23 24 void init() 25 { 26 27 int a,b,c; 28 for(int i=0; i<=n; i++)g[i].clear(); 29 for(int i=0; i<m; i++) 30 { 31 scanf("%d%d%d",&a,&b,&c); 32 g[a].push_back(node(b,c)); 33 } 34 scanf("%d",&a); 35 for(int i=0; i<a; i++) 36 { 37 scanf("%d",&b); 38 g[0].push_back(node(b,0)); 39 } 40 scanf("%d",&a); 41 for(int i=0; i<a; i++) 42 { 43 scanf("%d",&b); 44 g[b].push_back(node(n+1,0)); 45 } 46 } 47 48 void dijkstra(int start) 49 { 50 priority_queue<P,vector<P>,greater<P> >que; 51 memset(dist,INF,sizeof(dist)); 52 dist[start] = 0; 53 que.push(P(0,start)); 54 while(!que.empty()) 55 { 56 P p = que.top(); 57 que.pop(); 58 int v = p.second; 59 if(dist[v]<p.first)continue; 60 for(int i=0; i<g[v].size(); i++) 61 { 62 node e = g[v][i]; 63 if(dist[e.to] > dist[v] + e.w) 64 { 65 dist[e.to] = dist[v] + e.w; 66 que.push(P(dist[e.to],e.to)); 67 } 68 } 69 } 70 } 71 72 int main() 73 { 74 while(~scanf("%d%d",&n,&m)) 75 { 76 init(); 77 dijkstra(0); 78 printf("%d\n",dist[n+1]); 79 } 80 return 0; 81 }