【树的欧拉序列应用】学习&总结

这篇博客介绍了欧拉序在解决图论问题中的应用,特别是针对一棵树的最大边权查询。通过DFS构建欧拉序,并利用询问交互方式找出树中最大边权的边。代码示例展示了如何实现这一过程,主要涉及图的遍历和最大公因子的计算。
摘要由CSDN通过智能技术生成

前言

  1. 参考博客:oi-wiki
  2. 题目1要求:对欧拉序有个基本的印象先吧,然后多刷题!!

欧拉序介绍在这里插入图片描述

题目

题目1:欧拉序(任意一段序列所表示的边都是其中所有点中的几个点之间的简单路径)

  1. 传送门D. Hemose in ICPC ?
  2. 题意:给定一棵节点数为 n ≤ 3000 n\le 3000 n3000 的树,边权不知道,最多12次询问,每次询问返回这些点路径的中边权的最大公因子(其实就是返回这些边的所有简单路径中的最大边权)。求边权最大的边(返回两个值 u ,v ,其中 u-v 边为树中最大边),如果有多个答案,返回任意一个。
  3. 题解
    1. 提示:欧拉序。
    2. 另外,前人总结:交互问题,不是二分就是分块。
  4. 代码
#include <bits/stdc++.h>
using namespace std;
const int N = 1e6 + 100;  //无脑大空间

int n, u, v;
vector<int> g[N];
vector<int> b;
int cnt = 0, a[N];
void dfs(int x, int fa) {
    for (auto i : g[x]) {
        if (i == fa) continue;
        a[++cnt] = i;
        dfs(i, x);
        a[++cnt] = x;
    }
}
int query() {
    sort(b.begin(), b.end());
    b.erase(unique(b.begin(), b.end()), b.end());  //去重
    int sz = b.size();
    printf("? %d", sz);
    fflush(stdout);
    for (int i = 0; i < sz; i++) printf(" %d", b[i]), fflush(stdout);
    printf("\n");
    fflush(stdout);
    int x;
    scanf("%d", &x);
    return x;
}
signed main() {
    scanf("%d", &n);
    for (int i = 1; i < n; i++) {
        scanf("%d%d", &u, &v);
        g[u].push_back(v), g[v].push_back(u);
    }
    a[++cnt] = 1;
    dfs(1, -1);
    // for (int i = 1; i <= cnt; i++) cout << a[i] << ' ';
    // cout << endl;
    b.clear();
    for (int i = 1; i <= cnt; i++) b.push_back(a[i]);
    int mx = query();
    int l = 1, r = cnt;
    while (l + 1 < r) {
        int mid = (l + r) >> 1;
        b.clear();
        for (int i = l; i <= mid; i++) b.push_back(a[i]);
        // cout<<">>>"<<l<<" "<<mid<<endl;
        if (query() < mx)
            l = mid;  // l~mid-1不可能找到
        else
            r = mid;  // l~mid里面就可以找到
    }
    printf("! %d %d\n", a[l], a[r]);
    fflush(stdout);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值