首页 > 其他分享 >P3573 [POI2014]RAJ-Rally

P3573 [POI2014]RAJ-Rally

时间:2023-05-03 22:23:15浏览次数:55  
标签:std deg1 g1 int auto RAJ POI2014 vector Rally

网瘾犯了。

题意:在 DAG 上删除一点,使得剩下点的最长路最短。

解答:用 \(f_v\) 和 \(h_v\) 表示终点为 \(v\)、起点为 \(v\) 的单源最长路。按照拓扑序(这样才是 DAG,有 dp 性质)枚举 \(u\),每次先删除所有以 \(u\) 为起点的最长路,再更新答案,随后加入所有以 \(u\) 为起点的最长路。

复杂度:\(\mathcal O(n \log n)\)。

展开代码
#include <bits/stdc++.h>

using ll = long long;

int main() {
    std::cin.tie(nullptr)->sync_with_stdio(false);

    int n, m;
    std::cin >> n >> m;
    
    std::vector g1(n + 1, std::vector(0, 0)), g2 { g1 };
    std::vector deg1(n + 1, 0), deg2{ deg1 };
    
    while (m --) {
        int u, v;
        std::cin >> u >> v;
        g1[u].push_back(v), ++deg1[v];
        g2[v].push_back(u), ++deg2[u];
    }
    
    std::vector f(n + 1, 0), h { f };
    std::vector tsort{ 0 };
    
    auto kahn = [n, &tsort](const auto &g, auto &deg, auto &f) -> void {
        static bool flag = true;
        
        std::queue<int> q;
        for (int i = 1; i <= n; i++) {
            if (!deg[i]) {
                q.push(i);
                if (flag) tsort.push_back(i);
            }
        }
        while (!q.empty()) {
            int u = q.front();
            q.pop();
            for (int v : g[u]) {
                f[v] = std::max(f[v], f[u] + 1);
                if (!--deg[v]) {
                    q.push(v);
                    if (flag) tsort.push_back(v);
                }
            }
        }
        
        flag = false;
    };
    
    kahn(g1, deg1, f);
    kahn(g2, deg2, h);
    
    std::multiset<int> S;
    for (int i = 1; i <= n; i++) {
        S.insert(h[i]);
    }
    
    int id = 0, ans = *--S.end();
    for (int i = 1; i <= n; i++) {
        int u = tsort[i];
        
        S.erase(S.find(h[u]));
        for (int v : g2[u]) {
            S.erase(S.find(f[v] + h[u] + 1));
        }
        if (int res = *--S.end(); ans > res) {
            ans = res;
            id = u;
        }
        S.insert(f[u]);
        for (int v : g1[u]) {
            S.insert(f[u] + h[v] + 1);
        }
    }
    
    std::cout << id << ' ' << ans << '\n';
    
    return 0;
}

标签:std,deg1,g1,int,auto,RAJ,POI2014,vector,Rally
From: https://www.cnblogs.com/patricky/p/17369799.html

相关文章

  • P3573 [POI2014]RAJ-Rally 题解
    非常好题目,爱来自xc。看到有向无环图,想到拓扑序。通过拓扑序,可以轻松求出以每个点为起点的最长路\(disS\)与每个点为终点的最长路\(disF\)。如何求总共的最长路?在\(disS,disF,disS_u+1+disF_v((u,v)\inE)\)中取最大值即可。注意最后一项,表示将连边的二点值相加。......
  • rempe-2023-Trace and Pace: Controllable Pedestrian Animation via Guided Trajecto
    #TraceandPace:ControllablePedestrianAnimationviaGuidedTrajectoryDiffusion#paper1.paper-info1.1MetadataAuthor::[[DavisRempe]],[[ZhengyiLuo]],[[XueBinPeng]],[[YeYuan]],[[KrisKitani]],[[KarstenKreis]],[[SanjaFidler]],[[OrLi......
  • AGC002D Stamp Rally 多种做法 kruskal重构树/可持久化并查集/整体二分
    D-StampRally(atcoder.jp)这题做法很多,我写的是可持久化并查集做法,但是裸的可持久化并查集是$O(nlog^3n)$,能过但是很慢!看洛谷的题解有一位大佬写了一个很妙的并查集的写法,按秩合并,每一步合并时用vector记录一下这个被合并到的节点的size和当前的时间,这样做可以找到每一个时......
  • 强连通分量 - Kosaraju Algorithm
    推荐在唯一官方原文阅读,但本文不是转载,是多平台发布。Kosaraju算法(akaKosaraju-Sharir算法)是一个求强连通分量的算法。其时间复杂度为\(O(n+m)\)(邻接表)或\(O(m^2)\)(邻接矩阵)。该算法相比Tarjan算法要更简单一些。(个人观点)本算法的基础是反图(也被称作逆图、转置图)。基本原理......
  • 8064: yuyu的虚拟世界 kosaraju强连通分量
    描述 yuyu心情不太好,于是她进入了自己的虚拟世界,其中有n个小镇(1~n编号)和m条单向道,她随便选了一个点,沿着道路往前走,她发现自己可以无限的一直走下去,正好用来打发她的时间。现在她想知道,这个世界中能有几个这样的出发点,只要她选择合适的道路,总可能让她这样一直走下去。  ......
  • 【洛谷】P5904 [POI2014]HOT-Hotels(长链剖分)
    原题链接题意给出一棵有\(n\)个点的树,求有多少组点\((i,j,k)\)满足\(i,j,k\)两两之间的距离都相等。\((i,j,k)\)与\((i,k,j)\)算作同一组。\(1\len\le10^5\)......
  • P3574 [POI2014] FAR-FarmCraft 吐槽 + 题解
    洛谷上面的题解写的真的不太好,有很多错误,我来谈谈自己的理解。设\(f[i]\)表示以\(i\)为根节点的子树中(包括节点\(i\))的所有人安装好游戏所需要的时间(与下面的\(g[i]......
  • 【五期邹昱夫】CCF-A(SIGSAC'22)Membership Inference Attacks by Exploiting Loss Traj
    "Liu,Yiyong,etal."Membershipinferenceattacksbyexploitinglosstrajectory."Proceedingsofthe2022ACMSIGSACConferenceonComputerandCommunicatio......
  • P3571 [POI2014]SUP-Supercomputer 题解
    首先有一个结论,树中存在一个深度\(dep\),使得深度小于等于\(dep\)的点只需\(dep\)次覆盖完,而大于\(dep\)的除最后一次外其他每次都可以填充\(k\)次。证明:在\(dep......
  • kosarajo求强连通分量
    kosarajo求强连通分量的证明因为根据反向图的dfs求出的拓扑序列使得原本的dag图中点的搜索优先级倒转所以在原图dfs会优先将最末端的点优先跑完,而上面的点再跑时,因为下......