题目列表
http://acm.hdu.edu.cn/showproblem.php?pid=2680
5 8 5 1 2 2 1 5 3 1 3 4 2 4 7 2 5 6 2 3 5 3 5 1 4 5 1 2 2 3 4 3 4 1 2 3 1 3 4 2 3 2 1 1
1 -1
测试数据意思:
第一行三个数:n(车站的个数,n<1000) | m(代表车站之间所有线路的总个数) | s(代表离朋友家最近的车站)
下面有m行: p q t 意思是:一条从p到q的线路,花费t时间
m行之后有个数字:w (代表可以在开始时搭乘的车站)
下面w个数W1,W2....Ww就是车站的编号
思路:
逆向的找路径就好了,把终点当做起点,比较每个车站到终点的值,取最小的即可。我用的是Dijkstra的优先队列 优化做的。
先贴一下这个的模板。
/* Dijkstra的算法思想: 在所有没有访问过的结点中选出dis(s,x)值最小的x 对从x出发的所有边(x,y),更新 dis(s,y)=min(dis(s,y),dis(s,x)+dis(x,y)) */ #include <iostream> #include <cstdio> #include <queue> #include <vector> using namespace std; const int Ni = 10000; const int INF = 1<<27; struct node{ int x,d; node(){} node(int a,int b){x=a;d=b;} bool operator < (const node & a) const { if(d==a.d) return x<a.x; else return d > a.d; } }; vector<node> eg[Ni]; int dis[Ni],n; void Dijkstra(int s) { int i; for(i=0;i<=n;i++) dis[i]=INF; dis[s]=0; //用优先队列优化 priority_queue<node> q; q.push(node(s,dis[s])); while(!q.empty()) { node x=q.top();q.pop(); for(i=0;i<eg[x.x].size();i++) { node y=eg[x.x][i]; if(dis[y.x]>x.d+y.d) { dis[y.x]=x.d+y.d; q.push(node(y.x,dis[y.x])); } } } } int main() { int a,b,d,m; while(scanf("%d%d",&n,&m),n+m) { for(int i=0;i<=n;i++) eg[i].clear(); while(m--) { scanf("%d%d%d",&a,&b,&d); eg[a].push_back(node(b,d)); eg[b].push_back(node(a,d)); } Dijkstra(1); printf("%d\n",dis[n]); } return 0; } /* 6 6 1 2 2 3 2 4 1 4 5 2 5 2 3 6 3 5 6 3 */
#include <iostream> #include <cstdio> #include <queue> #include <vector> using namespace std; const int Ni = 20010; const int INF = 1<<27; struct node{ int x,d; node(){} node(int a,int b){x=a;d=b;} bool operator < (const node & a) const { if(d==a.d) return x<a.x; else return d > a.d; } }; vector<node> eg[Ni]; int dis[Ni],n; void Dijkstra(int s) { int i; for(i=0;i<=n;i++) dis[i]=INF; dis[s]=0; //用优先队列优化 priority_queue<node> q; q.push(node(s,dis[s])); while(!q.empty()) { node x=q.top(); q.pop(); for(i=0;i<eg[x.x].size();i++) { node y=eg[x.x][i]; if(dis[y.x]>x.d+y.d) { dis[y.x]=x.d+y.d; q.push(node(y.x,dis[y.x])); } } } } int main() { int a,b,d,m,s,t,minx,de; int w[1010]; while(~scanf("%d%d%d",&n,&m,&s)) { for(int i=0;i<=n;i++) eg[i].clear(); while(m--) { scanf("%d%d%d",&a,&b,&d); eg[b].push_back(node(a,d)); } scanf("%d",&t); minx=INF; Dijkstra(s); for(int i=0;i<t;i++) { scanf("%d",&w[i]); //printf("%d\n",dis[w[i]]); if(dis[w[i]]<minx) minx=dis[w[i]]; } if(minx==INF) printf("-1\n"); else printf("%d\n",minx); } return 0; }