首页 > 其他分享 >YACS 2023年10月月赛 甲组 题解

YACS 2023年10月月赛 甲组 题解

时间:2023-10-27 18:57:24浏览次数:47  
标签:YACS return 200005 int 题解 mx 甲组 dep find

目前只有 T2,其他题目我在看。

题目链接1

题目链接2

题目链接3

T2

很简单的一道题,将图分为若干个连通块,然后分别求最小生成树。

从货车运输中得到的结论,最小生成树等价于最小边权上限生成树,也就是它也能够保证选出边中最大的边权最小。

而题目中明确说了这个最小生成树的权值是其中边权的最大值。

思路就很明显了吧,求完最小生成树后对于每个连通块预处理倍增要用的,然后先求一遍 $k$ 个点的 $lca$,把所有点到 $lca$ 路径上边的最大值取个 $\max$ 输出即可。

至于 $INF$,也很好判,最小生成树用了一个并查集,只需要判所有点的祖先是否一样即可。

代码:

#include <bits/stdc++.h>
#define mp make_pair
#define For(i, a, b) for (int i = (a); i <= (b); i ++)
#define foR(i, a, b) for (int i = (a); i >= (b); i --)
using namespace std;
int n, m, q;
int c[200005], fa[200005], dep[200005];
int f[200005][18], mx[200005][18];
struct Edge {int u, v, w;}a[500005];
bool cmp (Edge e1, Edge e2) {return e1.w < e2.w;}
vector <pair <int, int> > G[200005];
bool vis[200005];
int find (int x) {
    if (fa[x] == x) return x;
    return fa[x] = find (fa[x]);
}
void dfs (int u, int val) {
    vis[u] = 1;
    mx[u][0] = val;
    For (i, 1, 17) {
        f[u][i] = f[f[u][i - 1] ][i - 1];
        mx[u][i] = max (mx[u][i - 1], mx[f[u][i - 1] ][i - 1]);
    }
    for (auto p : G[u]) {
        if (vis[p.first]) continue;
        f[p.first][0] = u;
        dep[p.first] = dep[u] + 1;
        dfs (p.first, p.second);
    }
}
int lca (int x, int y) {
    if (dep[x] < dep[y]) swap (x, y);
    foR (i, 17, 0) if (dep[f[x][i] ] >= dep[y]) x = f[x][i];
    if (x == y) return x;
    foR (i, 17, 0) if (f[x][i] != f[y][i]) {
        x = f[x][i];
        y = f[y][i];
    }
    return f[x][0];
}
int query (int x, int y) {
    int ret = 0;
    foR (i, 17, 0) {
        if (dep[f[x][i] ] >= dep[y]) {
            ret = max (ret, mx[x][i]);
            x = f[x][i];
        }
    }
    return ret;
}
void solve () {
    scanf ("%d%d%d", &n, &m, &q);
    For (i, 1, n) fa[i] = i;
    For (i, 1, m) scanf ("%d%d%d", &a[i].u, &a[i].v, &a[i].w);
    sort (a + 1, a + m + 1, cmp);
    For (i, 1, m) {
        int fx = find (a[i].u), fy = find (a[i].v);
        if (fx != fy) {
            fa[fx] = fy;
            G[a[i].u].push_back (mp (a[i].v, a[i].w) );
            G[a[i].v].push_back (mp (a[i].u, a[i].w) );
        }
    }
    For (i, 1, n) if (!vis[i]) {
        dep[i] = 1;
        dfs (i, 0);
    }
    while (q --) {
        int k;
        scanf ("%d", &k);
        For (i, 1, k) scanf ("%d", &c[i]);
        bool fi = 0;
        For (i, 2, k) {
            if (find (c[i]) != find (c[i - 1]) ) {
                printf ("INF\n");
                fi = 1;
                break;
            }
        }
        if (fi) continue;
        int l = c[1];
        For (i, 2, k) l = lca (l, c[i]);
        int ans = 0;
        For (i, 1, k) ans = max (ans, query (c[i], l) );
        printf ("%d\n", ans);
    }
}
signed main () {
    int _ = 1;
//    cin >> _;
    while (_ --) {
        solve ();
        cout << '\n';
    }
    return 0;
}

 

标签:YACS,return,200005,int,题解,mx,甲组,dep,find
From: https://www.cnblogs.com/Xy-top/p/17792984.html

相关文章

  • [NOI2010] 超级钢琴 题解
    [NOI2010]超级钢琴题解说点闲话原本不想写这个题解的但是看到我的代码居然长度为2048B->刚好2KiB,然后还跟题号相同QAQ题目翻译给你一段序列,求出其中从第\(1\)大到第\(k\)大的子区间的和。思路解析首先可以想到一个简单的暴力,对于每一个区间开头\(i\),和区间结尾\(j\),都求......
  • 2023 CSP-J2 T1,2,3题解
    今年的\(CSP−J\)对本蒟蒻来说有点难度。。。A[CSP-J2023]小苹果题目描述小Y的桌子上放着\(n\)个苹果从左到右排成一列,编号为从\(1\)到\(n\)。小苞是小Y的好朋友,每天她都会从中拿走一些苹果。每天在拿的时候,小苞都是从左侧第\(1\)个苹果开始、每隔\(2\)个......
  • [TJOI2013] 松鼠聚会 题解
    [TJOI2013]松鼠聚会题解切比雪夫距离切比雪夫距离指的是在平面上的两个点\((x_1,y_1)\),\((x_2,y_2)\)之间横纵坐标之差绝对值中的大者。用公式表示则是\(f(a,b)=max(|x_a-x_b|,|y_a-y_b|)\)。切比雪夫距离与曼哈顿距离之间可以相互转换切比雪夫—>曼哈顿:\((x_1,y_1)\),\((x......
  • [NOIP 2013提高组]货车运输 题解
    [NOIP2013提高组]货车运输题解前置知识Kruskal重构树(内含讲解)+任意一种LCA题目翻译\(n\)座城市,\(m\)条道路,\(q\)次询问,每次求两个点\(x,y\)之间所有路径的最小值的最大值。题目分析其实学了Kruskal重构树差不多看到这个题目就知道怎么写了。其实就是Kruskal重构树的板子,......
  • 问题解决
    pip源问题解决使用pip安装pytorch出现WARNING:Retrying(Retry(total=4,connect=None,read=None,redirect=None,status=None))报错使用换源解决问题pip3configlistpip3configsetglobal.index-urlhttps://mirrors.aliyun.com/pypi/simple/pip3configlist国内......
  • 第四章苏格拉底问答、实践过程截图、遇到问题解决问题截图,代码链接
    代码#include<stdio.h>#include<stdlib.h>#include<pthread.h>#defineN4intA[N][N],sum[N];void*func(voidarg){intj,row;pthread_ttid=pthread_self();row=(int)arg;printf("Thread%d[%lu]computessumofrow%d\n"......
  • Python打不开问题解决方案大全
    在使用Python进行编程开发的过程中,我们不可避免会遇到Python打不开的问题。这些问题可能是由于环境配置、包管理和依赖文件等问题所导致的,但不管是何种原因,我们都需要解决它们才能顺利地进行工作。本文将从多个方面为大家详细介绍Python打不开问题的解决方法。一、Python环境配......
  • Acwing393. 雇佣收银员 题解 差分约束
    题目链接:https://www.acwing.com/problem/content/description/395/解题思路:差分约束。为了方便起见,定义第\(i\)个时间段为\(i-1:00\)到\(i:00\)首先,为了方便开一个额外的点,令\(R_i\)对应为题目中的\(R(i+1)\),即\(R_i\)表示\(i-1:00\)到\(i:00\)这个时间段的最小需求......
  • AnyCAD程序无法启动的问题解决方法
    在某些电脑上会出现基于AnyCAD开发的程序无法启动的问题,如:System-ArgumentEcception:Pleasecheckthedependendes解决方法安装最新的VS运行时库,如VS2022:微软官方下载地址:x64:vc_redist.x64.exeSystem.AccessViolationException:"Attemptedtoreadorwriteprotectedmemor......
  • CF777题解
    分析先对每一列都做DP寻找极长单调不降区间,能够得到若干极长单调不降区间,只要询问的区间是这些区间的子区间,那么说明在这个区间内必有一列的这个区间是单调不降的。思考如何快速判断子区间。用\(f_{x}\)表示以\(x\)为所有左端点为\(x\)的区间的右端点最大值,那么对于......