题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2145
思路:题目很简单。。。关键是思想,如果你建图求的是每个点到终点的最短距离,那就TLE了,但仔细一想,我也可以建反向图啊!!!然后一次Dijkstra或者spfa就可以了。。。
最后排序即可。
View Code
1 #include<iostream> 2 #include<queue> 3 #include<vector> 4 #include<algorithm> 5 const int MAXN=333; 6 const int inf=1<<30; 7 using namespace std; 8 struct Person{ 9 int num,dist; 10 double time; 11 }person[MAXN]; 12 13 struct Node{ 14 int v,w; 15 }; 16 vector<Node>mp[MAXN]; 17 int n,m,k,p; 18 int dist[MAXN]; 19 int Pos[MAXN],Speed[MAXN]; 20 21 int cmp(const void *a,const void *b){ 22 Person *p=(Person *)a; 23 Person *q=(Person *)b; 24 if(p->time!=q->time){ 25 return p->time>q->time?1:-1; 26 }else if(p->dist!=q->dist){ 27 return q->dist-p->dist; 28 }else 29 return q->num-p->num; 30 } 31 32 33 34 void SPFA(int u){ 35 for(int i=1;i<=n;i++)dist[i]=inf; 36 dist[p]=0; 37 queue<int>Q; 38 Q.push(u); 39 while(!Q.empty()){ 40 int u=Q.front(); 41 Q.pop(); 42 for(int i=0;i<mp[u].size();i++){ 43 int v=mp[u][i].v; 44 int w=mp[u][i].w; 45 if(dist[u]+w<dist[v]){ 46 dist[v]=dist[u]+w; 47 Q.push(v); 48 } 49 } 50 } 51 } 52 53 54 55 int main(){ 56 while(~scanf("%d%d%d",&n,&m,&k)){ 57 for(int i=1;i<=n;i++)mp[i].clear(); 58 memset(person,0,sizeof(person)); 59 memset(Pos,0,sizeof(Pos)); 60 memset(Speed,0,sizeof(Speed)); 61 for(int i=1;i<=k;i++){ 62 int u,v,w; 63 scanf("%d%d%d",&u,&v,&w); 64 Node p; 65 p.v=u,p.w=w;//建反向图 66 mp[v].push_back(p); 67 } 68 scanf("%d",&p); 69 for(int i=1;i<=m;i++){ 70 scanf("%d",&Pos[i]); 71 } 72 for(int i=1;i<=m;i++){ 73 scanf("%d",&Speed[i]); 74 } 75 SPFA(p); 76 int l=0; 77 for(int i=1;i<=m;i++){ 78 if(dist[Pos[i]]<inf){ 79 person[l].num=i; 80 person[l].dist=dist[Pos[i]]; 81 person[l++].time=dist[Pos[i]]*1.0/Speed[i]; 82 } 83 } 84 if(l==0){ 85 printf("No one\n"); 86 }else { 87 qsort(person,l,sizeof(person[0]),cmp); 88 printf("%d\n",person[0].num); 89 } 90 } 91 return 0; 92 }