当前位置:首页 > 编程笔记 > 正文
已解决

[USACO23FEB] Moo Route II S 题解

来自网友在路上 160860提问 提问时间:2023-11-01 05:37:55阅读次数: 60

最佳答案 问答题库608位专家为你答疑解惑

比较有意思。

无法保证每个点只被访问一遍,而此题每条边显然不会重复走,考虑保证每条边仅走一次。

一种 naive 的想法就是标记边是否走过。举个例子:

for(int i=1; i<=n; i++)if(vis[i]) continue;

仍然是 O ( n ) 。 O(n)。 O(n)

然后就考虑每次只访问有必要的边。对 u u u 出边按 r r r 排序,二分找出当前时间下还有必要访问的边。排序后访问到一条走过的边,显然就不用继续遍历接下来的出边了。

#include<bits/stdc++.h>
#define int long long
using namespace std;const int N = 2e5 + 5;struct Edge{int c, r, d, s;bool vis;
};int n, m, a[N], dis[N];vector <Edge> G[N];void dfs(int u, int T)
{int l = 0, r = G[u].size() - 1, mid, pos = 1e9;while(l <= r){mid = l + r >> 1;if(G[u][mid].r >= T) pos = mid, r = mid - 1;else l = mid + 1;}for(int i = pos; i < G[u].size(); i ++ ){if(G[u][i].vis) return;G[u][i].vis = 1;int to = G[u][i].d;if(G[u][i].s < dis[to]) dis[to] = G[u][i].s, dfs(to, G[u][i].s + a[to]);}
}signed main()
{ios::sync_with_stdio(0); cin.tie(0);cin >> n >> m;for(int i=1; i<=m; i++){Edge x; x.vis = 0;cin >> x.c >> x.r >> x.d >> x.s;G[x.c].push_back(x);}for(int i=1; i<=n; i++)cin >> a[i], dis[i] = 1e9;for(int i=1; i<=n; i++) sort(G[i].begin(), G[i].end(), [](Edge &x, Edge &y){return x.r < y.r;});dis[1] = 0;dfs(1, 0);for(int i=1; i<=n; i++){if(dis[i] == 1e9) cout << "-1\n";else cout << dis[i] << "\n";} 
}
查看全文

99%的人还看了

猜你感兴趣

版权申明

本文"[USACO23FEB] Moo Route II S 题解":http://eshow365.cn/6-29200-0.html 内容来自互联网,请自行判断内容的正确性。如有侵权请联系我们,立即删除!