HRBEU ACM 图论1001
http://acm.hrbeu.edu.cn/index.php?act=problem&id=1001&cid=22
题目是最短路的一个小变形。我们平时求的最短路都只是包含固定的长度,这里加了一个过红绿灯的时间。所以再走到一个路口时要判断是红灯还是绿灯。在更新辅助数组的时候,如果碰见的是绿灯那就无所了,但是如果碰见的是红灯,则要把等红灯的时间考虑上。
其实只要知道了如何判断是红灯还是绿灯,这道题还是很简单的。
判断是绿灯的条件为:
(1) map[i][j].t==0
(2) ((dis[j]+map[j][i].t)/map[j][i].t)%2==1;
当然其他的就是红灯的情况了
#include<stdio.h> #include<string.h> #include<iostream> using namespace std; #define INF 99999999 #define N 30 int sx,ey,n; int maxx,minx; int v[N],dis[N]; struct node { //char s,e; int di; int t; }map[N][N]; void dijstra() { int i,j,k; for(i=0;i<N;i++) { v[i]=0;dis[i]=INF; } dis[sx]=0; for(k=minx;k<maxx;k++) { int minn=INF; for(i=minx;i<=maxx;i++) { if(!v[i]&&dis[i]<minn) { minn=dis[i]; j=i; } } v[j]=1; for(i=minx;i<=maxx;i++) { if(!map[j][i].t||((dis[j]+map[j][i].di)/map[j][i].t)%2) //如果是绿灯,则直接过就可以了 { if(dis[i]>dis[j]+map[j][i].di) dis[i]=map[j][i].di+dis[j]; } else { if(map[j][i].t-(dis[j]+map[j][i].di)%map[j][i].t+dis[j]+map[j][i].di<dis[i]) //map[j][i].t-(map[j][i].di+dis[j])%map[j][i].t为等红灯的时间。 dis[i]=map[j][i].t-(dis[j]+map[j][i].di)%map[j][i].t+dis[j]+map[j][i].di; } } } cout<<dis[ey]<<endl; } int main() { int cs; int i,j; char s,e; cin>>cs; while(cs--) { cin>>n; for(i=0;i<N;i++) { for(j=0;j<=N;j++) map[i][j].di=INF; } maxx=-1;minx=INF; for(i=0;i<n;i++) { cin>>s>>e; if(s-'a'>maxx) maxx=s-'a';//起点和终点并非是0和n,所以要记录下来 if(s-'a'<minx) minx=s-'a'; if(e-'a'<minx) minx=e-'a'; if(e-'a'>maxx) maxx=e-'a'; cin>>map[s-'a'][e-'a'].di>>map[s-'a'][e-'a'].t; } cin>>s>>e; sx=s-'a'; ey=e-'a'; dijstra(); } return 0; }