首页 > 其他分享 > Codeforces Round 898 (Div. 4)

Codeforces Round 898 (Div. 4)

时间:2023-09-30 21:34:38浏览次数:37  
标签:std dep 898 auto Codeforces bfs int Div dis

由于题目补完才来写总结,导致前面的有的题目都需要重新再看一遍,只好当作复习了。
但考虑到趁热打铁,先看H.

  • H题:从小白视角来看乍一看是博弈论,仔细思考以后发现是图论。本题给的是基环树,意识到这一点很重要,这个条件是让本题不是很复杂的关键。n个点n条边且没有重边保证这个联通图中只有一个环。由于瓦能够预测马去哪,当双方在环上时,瓦永远不会被抓到。若开始时瓦不在环上,则瓦的最优策略是找到去环上的最短路,而马的策略尽可能先到环去拦截瓦。

梳理一下逻辑顺序,在环上找到离b最近的一点u,a如果能提前到u,则b就会被拦截。只需比较a到u的最短路和b到u的最短路大小就可以。

以上为算法思路,下面考虑用什么去实现上面这个思路?

首先dfs找到环,再bfs得到瓦到环上哪个点最近,确定u点后,再bfs找到a到u的最短距离。
bfs找最短路过程朴素,注意力放到dfs过程我学习到的点:
1.记录par父节点数组是为了能遍历环的时候找回去,找到环中距离b点最近的点。
2.对于只有一个环,利用dep深度数组去找,如果当前点x可拓展的点深度和dep[x]大小差2还能连在一起,则起码构成一个最小的三角环,建议自己画图理解dfs深度和环的关系。

#include <bits/stdc++.h>

using i64 = long long;

void solve() {
    int n, a, b;
    std::cin >> n >> a >> b;
    a--, b--;
    
    std::vector<std::vector<int>> adj(n);
    for (int i = 0; i < n; i++) {
        int u, v;
        std::cin >> u >> v;
        u--, v--;
        adj[u].push_back(v);
        adj[v].push_back(u);
    }
    //在连通图中找到所有点离某个点的最短距离,返回的是一个vector
    //内部lambda函数的好处是可以不用预处理,随时执行,并可以将函数定义为变量
    auto bfs = [&](int s) {
        std::vector<int> dis(n, -1);
        dis[s] = 0;
        std::queue<int> q;
        q.push(s);
        
        while (!q.empty()) {
            int x = q.front();
            q.pop();
            
            for (auto y : adj[x]) {
                if (dis[y] == -1) {
                    dis[y] = dis[x] + 1;
                    q.push(y);
                }
            }
        }
        return dis;
    };
    auto dis = bfs(b);
    
    int u = -1;
    std::vector<bool> vis(n);
    std::vector<int> par(n), dep(n);
    auto dfs = [&](auto self, int x) -> void {
        vis[x] = true;
        for (auto y : adj[x]) {
            if (!vis[y]) {
                par[y] = x;
                dep[y] = dep[x] + 1;
                self(self, y);
            } else if (dep[y] < dep[x] - 1) {//利用深度关系找到环
                for (int i = x; ; i = par[i]) {
                    if (u == -1 || dis[i] < dis[u]) {
                        u = i;//dijstra的模式找最短路,把第一次的情况u==-1的情况也考虑进去,可以一行特判我们应该固化下来
                    }//找到环中距离b点最近的点
                    if (i == y) {
                        break;
                        //环走完了,该及时退出循环
                    }
                }
            }
        }
    };
    dfs(dfs, 0);
    
    if (bfs(u)[a] > dis[u]) {
        std::cout << "YES\n";
    } else {
        std::cout << "NO\n";
    }
}

int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    
    int t;
    std::cin >> t;
    
    while (t--) {
        solve();
    }
    
    return 0;
}

标签:std,dep,898,auto,Codeforces,bfs,int,Div,dis
From: https://www.cnblogs.com/mathiter/p/17738257.html

相关文章

  • Codeforces Round 900 (Div. 3)
    目录写在前面ABCDEFG写在最后写在前面比赛地址:https://codeforces.com/contest/1878。前天晚上他妈睡不着觉又不想看漫画打游戏于是到阳台上开把div3放松心情。40min过了5题把剩下两题都口了感觉没意思了于是睡觉。太菜了还是,现在是div3随便AK但是div2过不了E的......
  • Educational Codeforces Round 122 (Rated for Div. 2)
    A.Div.7#include<bits/stdc++.h>usingnamespacestd;voidsolve(){intn,a,b,c;cin>>n;c=n%10,n/=10;b=n%10,n/=10;a=n%10,n/=10;intres,val=100;for(inti=0;i<=9......
  • Go每日一库之138:dive(Docker 镜像分析)
    什么是dive?用于探索Docker镜像、每一层中的内容以及发现缩小Docker/OCI镜像大小的方法的工具。安装divego get github.com/wagoodman/divedive特性按层分解Docker镜像可视化展示每一层变化分析镜像空间使用百分比快速构建分析镜像支持多种镜像源和容器引擎......
  • Educational Codeforces Round 155 (Rated for Div. 2)
    Preface这天晚上这场因为不明原因(玩CCLCC中)就没有打,只能赛后补一下这场的EF都不算难初看都有做法,但好家伙E写挂两发,F写个根号做法直接T到天上去了A.Rigged!签到题,对于所有的\(e_i\gee_1\)的\(i\),求出\(S=\maxs_i\),根据\(S+1\)和\(s_1\)的大小关系判断即可#include<cstdio......
  • Codeforces Round 695 (Div. 2)
    练习笔记:A:https://codeforces.com/contest/1467/problem/A一开始以为是987654321.....交了两发WA。慢慢想想就是如果说我是第二个号码放8就是98901234....交了就是AC B:https://codeforces.com/contest/1467/problem/BB啊,暴力打出来对于每个i,他在可能是a[i-1]-1,a[i-1]......
  • 加训日记 Day5——codeforces round 899 再战div2
    Day5,9.25,codeforcesround899div2  ·事实证明自己的思维和手速都还不够快,晚上还晚来了一点  ·B题属实是,上来就想着并查集(菜鸡是这样的)然后发现不会写捏  ·思考了很久(看数据量)感觉是枚举暴力,但是又想不到怎么去枚举  ·一题遗憾离场  ·顺理成章的-26......
  • 加训日记 Day6——来场div3上上分(为什么连着三天比赛啊喂,人要熬死了)
    Day6,9.26cfround900div3  ·前三题手速题,尝试用模板和库函数结果出了点岔子,罚时略高  ·感觉还有很大提升空间,觉得这种题应该要求自己10分钟内全过掉(开翻译的情况下)  ·D过的人数没有E多就很难绷  ·写了发D结果TLEon10,心态爆炸直接下播  ·美美+46......
  • Problem - 616C - Codeforces
    Problem-616C-CodeforcesC.TheLabyrinth如果是直接对\(*\)去跑dfs或者bfs的话无疑是会超时的既然如此,那我们可以去对\(.\)跑搜索,将各个连通的\(.\)块标号并计算出连通块内的点的数量,然后去遍历\(*\)的时候只需要上下左右跑一下计算即可啊,在\(bfs\)或\(dfs\)的时......
  • CF957 Codeforces Round 472 (rated, Div. 2, based on VK Cup 2018 Round 2)
    CF957ATritonicIridescence如果原序列中有两个相同的字符,显然不合法。如果开头或者结尾为?,或者有两个连续的?,或者一个?两边的字符不同显然合法。否则一定不合法。#include<iostream>#include<cstdio>usingnamespacestd;constintN=105;intn;chars[N];intma......
  • CF992 Codeforces Round 489 (Div. 2)
    CF992ANastyaandanArray答案为非零数的个数。#include<iostream>#include<cstdio>#include<map>usingnamespacestd;constintN=100005;intn;inta[N];map<int,int>cnt;intmain(){ scanf("%d",&n); for(inti=1;i<=n;i+......