其他分享
首页 > 其他分享> > [CF1693C]Keshi in Search of AmShZ 题解

[CF1693C]Keshi in Search of AmShZ 题解

作者:互联网

传送门QAQ

参考题解

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