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;
}

浙公网安备 33010602011771号