BZOJ 3245: 最快路线

题目大意:精明的小R每每开车出行总是喜欢走最快路线,而不是最短路线.很明显,每条道路的限速是小R需要考虑的关键问题.不过有一些限速标志丢失了,于是小R将不知道能开多快.不过有一个合理的方法是进入这段道路时不改变速度行驶.你的任务就是计算从小R家(0号路口)到D号路口的最快路线.
现在你得到了这个城市的地图,这个地图上的路都是单向的,而且对于两个路口A和B,最多只有一条道路从A到B.并且假设可以瞬间完成路口的转弯和加速.

BZOJ的source已经暴露了一切…直接上spfa,对于一个点记录到达它时的速度,然后进行转移,基本上就是一个分层图的思路吧。因为要输出方案,多开一个数组记录就行了。

#include
#include
#include
#include
#include
#include
using namespace std;
const int maxn=150+10;
const int maxv=500+10;
int inq[maxn][maxv],n,m,d,out[maxn],tot;
double dis[maxn][maxv];
struct edge
{
  int to,v,l;
};
struct node
{
  int p,v;
}go[maxn][maxv];
vector g[maxn];
queue Q;
int main()
{
  //freopen("3245.in","r",stdin);
  //freopen("3245.out","w",stdout);
  scanf("%d%d%d",&n,&m,&d);d++;
  for(int i=1;i<=m;i++)
  {
    int a,b,v,l;
    scanf("%d%d%d%d",&a,&b,&v,&l);a++;b++;
    g[a].push_back((edge){b,v,l});
  }
  for(int i=0;i<=n;i++) for(int j=0;j<=500;j++) dis[i][j]=1000000000;
  dis[1][70]=0;inq[1][70]=0;Q.push((node){1,70});
  while(!Q.empty())
  {
    node x=Q.front();Q.pop();inq[x.p][x.v]=0;
    for(int i=0;iint np=e.to,nv=e.v;
      if(!nv) nv=x.v;double cc=(double)e.l/(double)nv;
      if(dis[np][nv]>dis[x.p][x.v]+cc)
      {
        dis[np][nv]=dis[x.p][x.v]+cc;
        go[np][nv]=(node){x.p,x.v};
        if(!inq[np][nv])
        {
          inq[np][nv]=1;
          Q.push((node){np,nv});
        }
      }
    }
  }
  double ans=1000000000.00;int hp=d,hv;
  for(int i=1;i<=500;i++)
    if(dis[d][i]//cout<
  while(go[hp][hv].p)
  {
    out[++tot]=go[hp][hv].p;
    int tp=hp,tv=hv;
    hp=go[tp][tv].p;hv=go[tp][tv].v;
  }
  for(int i=tot;i;i--) printf("%d ",out[i]-1);
  printf("%d\n",d-1);
  return 0;
}

你可能感兴趣的:(BZOJ 3245: 最快路线)