[CF1693C]Keshi in Search of AmShZ 题解
作者:互联网
Analysis
这题一眼看上去整的跟概率一样,导致我压根不想做(概率渣
但是我们可以分析一下:在 \(d\) 天内走到 \(n\) 点的条件是什么?
设点 \(x\) 到达 \(n\) 的最小天数为 \(d_x\)。
考虑 \(x\) 点的出边为 \((x,y_i)\),用 \(d_{y_i}\) 更新 \(d_x\)。
如果我们想走 \(y_i\),就必须把 \(d_{y_j}\) 更大的 \((x,y_j)\) 全部封锁,否则无法在 \(d_x\) 天内走到 \(n\)。
而 \(d\) 值更小的其它 \(y_k\) 我们是不用封锁的,因为走这些边也能在 \(d_x\) 天内走到。
所以,将所有的 \(y\) 按照 \(d_y\) 大小升序排序,就能依次用 \(d_{y_i} + deg_x- i\) 更新 \(d_x\)。
因为要先知道 \(d_y\) 再知道 \(d_x\),不妨建反图,从 \(n\) 反推回 \(1\),图中用类似 dijkstra
的方法不断让 \(d_x \gets d_y+deg_x\),每更新一次 \(deg_x \gets deg_x-1\) 即可。
最后的答案即为 \(d_1\)。
时间复杂度同 dijkstra
,为 \(O(N\log N)\)。
#include <bits/stdc++.h>
using namespace std;
const int maxn = 2e5 + 5;
typedef pair<int,int> pa;
#define pb emplace_back
#define mp make_pair
#define fir first
#define sec second
int d[maxn],deg[maxn];
bool vis[maxn];
const int INF = 0x3f3f3f3f;
vector<int> g[maxn];
priority_queue<pa,vector<pa>,greater<pa> > q;
int n,m;
int main() {
scanf("%d%d",&n,&m);
for(int i = 1;i <= m;++ i) {
int u,v;
scanf("%d%d",&u,&v);
++ deg[u];
g[v].pb(u);
}
for(int i = 1;i <= n;++ i)d[i] = INF;
d[n] = 0;
q.push(mp(d[n] , n));
while(!q.empty()) {
int u = q.top().sec;
q.pop();
if(vis[u])continue ;
vis[u] = true;
for(auto v : g[u]) {
if(d[v] > d[u] + deg[v]) {
d[v] = d[u] + deg[v];
q.push(mp(d[v] , v));
}
-- deg[v];
}
}
printf("%d",d[1]);
return 0;
}
完结撒花✿✿ヽ(°▽°)ノ✿
标签:Search,int,题解,Keshi,maxn,define,天内,deg 来源: https://www.cnblogs.com/663B/p/16434288.html