导航软件 CH Round #57

题目:http://ch.ezoj.tk/contest/CH%20Round%20%2357%20-%20Story%20of%20the%20OI%20Class/导航软件

题解:刚开始看见题目,这不是裸的分层图spfa吗?

        于是开始写代码,读边的时候忽然发现居然还有红绿灯,我说不会这么简单的,那这题一定很神。。。

        于是滚去做vijos

        看了题解一口血喷出来啊。。。

        事后想了想,貌似不管红绿灯什么事,走多少是多少?来的早至少不会比来得迟的过得晚。。。

        T_T

计算有红绿灯时通过的时间时需要好好yy一下,注释写在代码里

代码:

  1 #include<cstdio>
  2 #include<cstdlib>
  3 #include<cmath>
  4 #include<cstring>
  5 #include<algorithm>
  6 #include<iostream>
  7 #include<vector>
  8 #include<map>
  9 #include<set>
 10 #include<queue>
 11 #include<string>
 12 #define inf 1000000000
 13 #define maxn 50005
 14 #define maxm 500+100
 15 #define eps 1e-10
 16 #define ll long long
 17 #define pa pair<int,int>
 18 #define for0(i,n) for(int i=0;i<=(n);i++)
 19 #define for1(i,n) for(int i=1;i<=(n);i++)
 20 #define for2(i,x,y) for(int i=(x);i<=(y);i++)
 21 #define for3(i,x,y) for(int i=(x);i>=(y);i--)
 22 #define mod 1000000007
 23 using namespace std;
 24 inline int read()
 25 {
 26     int x=0,f=1;char ch=getchar();
 27     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
 28     while(ch>='0'&&ch<='9'){x=10*x+ch-'0';ch=getchar();}
 29     return x*f;
 30 }
 31 struct edge{int go,next,w,t1,t2;}e[6*maxn];
 32 int n,m,k,s,t,tot,d[maxn][21],head[maxn];
 33 queue<pa> q;
 34 bool v[maxn][21];
 35 inline void insert(int x,int y,int t1,int t2,int z)
 36 {
 37     e[++tot].go=y;e[tot].w=z;e[tot].next=head[x];head[x]=tot;e[tot].t1=t1;e[tot].t2=t2;
 38     e[++tot].go=x;e[tot].w=z;e[tot].next=head[y];head[y]=tot;e[tot].t1=t1;e[tot].t2=t2;
 39 }
 40 int calc(int ti,int t1,int t2,int t)
 41 {
 42     if(!t2)return ti+t;
 43     if(!t1)return inf;
 44     int res=ti;
 45     while(t)
 46     {
 47         int tmp=res%(t1+t2);
 48         if(!tmp)
 49          {
 50              if(t%t1)res+=t/t1*t2+t;//需要走t/t1个时间段,而在此之间等待的时间就为t/t1*t2 
 51              else res+=(t/t1-1)*t2+t;//少等待一个t2,因为最后一次已经走过这条路 
 52              t=0;
 53          }
 54         else if(tmp<t1)
 55          {
 56          if(t<=t1-tmp)res+=t,t=0;
 57          else res+=t1-tmp,t-=t1-tmp;//暴力模拟只走这一段 
 58          }
 59         else res+=t1+t2-tmp;//等待 
 60     }
 61     return res;
 62 }             
 63 int spfa()
 64 {
 65     memset(d,60,sizeof(d));
 66     d[s][0]=0;q.push(pa(s,0));
 67     while(!q.empty())
 68     {
 69         int x=q.front().first,z=q.front().second;q.pop();v[x][z]=0;
 70         for(int i=head[x];i;i=e[i].next)
 71         {
 72             int y=e[i].go;
 73             if(z<k&&d[x][z]+e[i].w<d[y][z+1])
 74              {
 75                  d[y][z+1]=d[x][z]+e[i].w;
 76                  if(!v[y][z+1]){v[y][z+1]=1;q.push(pa(y,z+1));}
 77              }
 78             int tmp=calc(d[x][z],e[i].t1,e[i].t2,e[i].w);
 79             if(tmp<d[y][z])
 80              {
 81                 d[y][z]=tmp;
 82                 if(!v[y][z]){v[y][z]=1;q.push(pa(y,z));}
 83              }
 84         }
 85     }
 86     int ans=inf;
 87     for0(i,k)ans=min(ans,d[t][i]);
 88     return ans;
 89 }
 90 int main()
 91 {
 92     freopen("input.txt","r",stdin);
 93     freopen("output.txt","w",stdout);
 94     n=read();m=read();k=read();
 95     for1(i,m)
 96     {
 97         int x=read(),y=read(),t1=read(),t2=read(),z=read();
 98         insert(x,y,t1,t2,z);
 99     }
100     s=read();t=read();
101     printf("%d
",spfa());
102     return 0;
103 }
View Code
原文地址:https://www.cnblogs.com/zyfzyf/p/4068916.html