题意:给出n个点,m条路,每条路用5个整数表示u,v,a,b,t
u表示这条路的起点,v表示终点,a表示打开时间,b表示关闭时间,t表示通过这条道路需要的时间
看的紫书,因为边权不再仅仅是路上的时间,还需要处理一下是否需要等待
如果不需要等待的话,这条路上的权值就为t
如果需要等待的话,这条路的权值就为t+wait
再用dijkstra就可以了
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include <cmath> 5 #include<stack> 6 #include<vector> 7 #include<map> 8 #include<set> 9 #include<queue> 10 #include<algorithm> 11 using namespace std; 12 13 #define foreach(i,c) for (__typeof(c.begin()) i = c.begin(); i != c.end(); ++i) 14 15 typedef long long LL; 16 const int INF = (1<<30)-1; 17 const int mod=1000000007; 18 const int maxn=100005; 19 20 int d[maxn],used[maxn],next[maxn],first[maxn]; 21 int n,m,ecnt,s,t; 22 23 struct edge{ 24 int v,a,b,t; 25 } e[maxn]; 26 27 void addedge(int u,int v,int a,int b,int t){ 28 next[++ecnt]=first[u]; 29 e[ecnt].v=v; 30 e[ecnt].a=a; 31 e[ecnt].b=b; 32 e[ecnt].t=t; 33 first[u]=ecnt; 34 } 35 36 void dijkstra(int s){ 37 for(int i=1;i<=n;i++) d[i]=INF; 38 d[s]=0; 39 memset(used,0,sizeof(used)); 40 41 for(int k=1;k<=n;k++){ 42 int u,m=INF; 43 for(int i=1;i<=n;i++) if(!used[i]&&d[i]<m) m=d[u=i]; 44 used[u]=1; 45 for(int i=first[u];i!=-1;i=next[i]){ 46 int v=e[i].v,a=e[i].a,b=e[i].b,t=e[i].t; 47 48 if(a<t) continue;//打开的时间小于通过的时间 49 50 int now=d[u]%(a+b); 51 if(now+t<=a){//现在能够通过的情况下松弛 52 if(d[v]>d[u]+t) d[v]=d[u]+t; 53 } 54 else{ 55 int wait=a+b-now;//现在需要等待的情况下松弛 56 if(d[v]>d[u]+wait+t) d[v]=d[u]+wait+t; 57 } 58 } 59 } 60 61 } 62 63 int main(){ 64 int kase=0; 65 while(scanf("%d %d %d %d",&n,&m,&s,&t)!=EOF){ 66 memset(first,-1,sizeof(first)); 67 ecnt=0; 68 69 while(m--){ 70 int u,v,a,b,t; 71 cin>>u>>v>>a>>b>>t; 72 addedge(u,v,a,b,t); 73 } 74 dijkstra(s); 75 76 printf("Case %d: ",++kase); 77 printf("%d\n",d[t]); 78 } 79 return 0; 80 }