UVa 12661 Funny Car Racing【 dijkstra 】

本文介绍了一种特殊情形下的最短路径问题求解方法,即在边权不仅包含通过时间还需考虑等待时间的问题中,如何使用Dijkstra算法进行有效解决。文章通过具体的代码实现展示了如何判断等待条件并据此更新路径权重。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题意:给出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 }
View Code

 

转载于:https://www.cnblogs.com/wuyuewoniu/p/4483523.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值