(热身赛暂时没链接)
给出一个n个点m条边的图
每条边表示u -> v 所需的时间 (小时)
某人驾车从s -> t 点 他一天最多能开15小时车
问他最少几天到达终点
直接当作最短路会产生问题
比如:
A->B->C->D-> E 每两点间需要7 h 则需要两天
A -> X -> X -> E 每两点需要9h 则需要三天
所以想到用bfs + 最短路
每次从某个点跑最短路Dij将 15个小时内能到达的所有点 压入queue
因为15个小时能跑到的最远点 对于天数而言是等距离的点
在bfs 时 则将队列头 (较早遍历的点) 弹出 以这个点为根 再次跑最短路Dij 更新下一个点
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104
| #include <bits/stdc++.h> using namespace std; typedef long long ll; #define endl '\n' #define P pair<ll,ll> const int Max=1e5+5; const ll Mod=1e9+7; const ll inf=0x3f3f3f3f; vector<P>mp[Max]; ll dis[Max]; int day[Max]; bool vis[Max],vis2[Max]; ll version[Max]; ll curver = 1; queue<int>qq;
void update(int now){ if(version[now]<curver){ vis[now] = 0; dis[now] = inf; version[now] = curver; } }
void Dijkstar(int st){ priority_queue<P,vector<P>,greater<P> >q; q.push({0,st}); update(st); dis[st]=0; while(!q.empty()){ auto temp=q.top();q.pop(); int now=temp.second; update(now); if(vis[now])continue; vis[now]=1; cout<<">>>>>from: "<<now<<endl; for(auto i:mp[now]){ int to=i.first; ll cost=i.second; update(to); if(day[to]<=day[st])continue; if(dis[now]+cost<min(16ll,dis[to])){ dis[to]=dis[now]+cost;
q.push({dis[to],to}); qq.push(to); day[to]=day[st]+1; } } } }
void bfs(int st){ qq.push(st);dis[st]=0; memset(day,0x3f,sizeof day); day[st]=0;int lastday=-1; while(!qq.empty()){ int now=qq.front();qq.pop(); if(vis2[now])continue; vis2[now]=1;
if(day[now]>lastday){ } curver++; Dijkstar(now); lastday=day[now]; } }
int main(){ int n,m,s,t; cin>>n>>m>>s>>t; for(int i=1;i<=m;i++){ int u,v,k; cin>>u>>v>>k; mp[u].push_back({v,k}); mp[v].push_back({u,k}); } bfs(s); cout<<day[t]<<endl; }
|