寒假集训第五天---最短路
Posted wifepi
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了寒假集训第五天---最短路相关的知识,希望对你有一定的参考价值。
CodeForces - 229B Planets
题目大意:给你m条边的无向图,边权代表从一个点到另一个点的花费时间,每个点给你k个时间点,表示如果你在ki时刻到达该顶点,你需要等待一秒。问从顶点1到顶点n的最少耗时是多少。
题解:正常跑最短路,在松弛的时候判断这个点需要等待多少秒再出发。
卡点:对于一个点来说我可能等待多秒,对于起点我可能也要等待(wa7),对于每个点我不需要重复计算等待时间,我只需要计算我目前这个点要想出发我需要等待多少时间,用这个时间去松弛他所能更新的边。对于我堆优化的dijkstra来说,堆上面的点的出发时间一定小于等于我下面的点的出发时间,相当于把考虑到时间后的最短路的问题抛给了优先队列自己去选择。妙哉
代??
#include <iostream> #include <cstdio> #include <queue> #include <algorithm> #include <string> #include <cstring> using namespace std; int cnt = 0 ; const int maxn = 1e5 + 10 ; const int inf = 0x3f3f3f3f ; #define ll long long ll MAX ; int head[maxn] ; int vis[maxn] ; int dis[maxn] ; vector<int> ve[maxn] ; int n, m, k ; struct Edge { int from, to, dist, next ; }edge[maxn<<1] ; void add(int from, int to, int dist) { ++ cnt ; edge[cnt].from = from ; edge[cnt].to = to ; edge[cnt].dist = dist ; edge[cnt].next = head[from] ; head[from] = cnt ; } struct node { int index, dist ; bool operator < (const node &x)const { return dist > x.dist ; } }; priority_queue<node> q ; int main(int argc, char const *argv[]) { memset(head,0,sizeof head) ; memset(vis,0,sizeof vis) ; scanf("%d %d",&n,&m) ; for(int i = 1, from, to, dist ; i <= m ; ++ i) { scanf("%d %d %d",&from,&to,&dist) ; add(from,to,dist) ; add(to,from,dist) ; } for(int i = 1, tt, tmp ; i <= n ; ++ i) { scanf("%d",&tt) ; for(int j = 0 ; j < tt ; ++ j) { scanf("%d",&tmp) ; ve[i].push_back(tmp) ; } } for(int i = 1 ; i <= n ; ++ i) dis[i] = inf ; int pos = lower_bound(ve[1].begin(),ve[1].end(),0) - ve[1].begin() ; while(pos < ve[1].size() && pos == ve[1][pos]) ++ pos ; dis[1] = pos ; q.push(node{1,0}) ; while(!q.empty()) { node x = q.top() ; q.pop() ; int u = x.index ; if(vis[u]) continue ; vis[u] = 1 ; int tmp = 0 ; int pos = lower_bound(ve[u].begin(),ve[u].end(),dis[u]) - ve[u].begin() ; while(pos < ve[u].size() && ve[u][pos] == dis[u] + tmp) ++ tmp, ++ pos ; for(int i = head[u] ; i ; i = edge[i].next) { if(dis[edge[i].to] > dis[u] + edge[i].dist) { if(dis[edge[i].to] > dis[u] + edge[i].dist + tmp) { dis[edge[i].to] = dis[u] + edge[i].dist + tmp ; q.push(node{edge[i].to,dis[edge[i].to]}) ; } } } } printf("%d ",dis[n] == inf ? -1 : dis[n]) ; return 0; }
以上是关于寒假集训第五天---最短路的主要内容,如果未能解决你的问题,请参考以下文章