首页 > 其他分享 >[CF1804F] Approximate Diameter 题解

[CF1804F] Approximate Diameter 题解

时间:2024-03-01 11:58:02浏览次数:15  
标签:return int 题解 mid Approximate CF1804F using ttt define

题目链接

题目分析

显然图结构不太好维护,容易想到维护树结构。维护生成树看起来就不太靠谱,容易想到维护最短路树。

key observation:我们固定一个端点(不妨为 \(1\)),求出这个点到每个点的最短路长度的最大值 \(x\)。则一定有 \(\lceil{d\over 2}\rceil\le x\le d\)。

证明:显然 \(x \le d\)。设直径为 \(u \rightsquigarrow v\),考虑 \(1 \rightsquigarrow u\) 和 \(1 \rightsquigarrow v\) 两条最短路,根据三角形不等式,这两条最短路的长度之和一定不小于 \(d\),因此其中较大者一定至少为 \(\lceil{d\over 2}\rceil\)。

考虑动态维护以 \(1\) 为根的最短路树,发现至少需要一棵 LCT。有没有更简单的方法呢?发现我们还没有用到 \(x\) 可以大于 \(d\)(只要不超过 \(2d\))这一性质。容易发现答案是单调不增的,因此答案减半的次数不超过 \(\log n + O(1)\),每次二分搜索求出第一次折半的位置即可。求最短路可以使用 BFS。时间复杂度 \(O(n \log^2 n)\)。

代码实现

#include <bits/stdc++.h>

#define FOR(i, l, r) for (int i = l; i < (r); ++i)
#define F0R(i, r) FOR (i, 0, r)
#define ROF(i, l, r) for (int i = r; i-- > (l);)
#define R0F(i, r) ROF (i, 0, r)
#define rep(n) F0R (_, n)
#define each(i, x) for (auto& i : x)

using namespace std;

using ll = long long;
using db = long double;
using str = string;

using pi = pair<int, int>;
#define mp make_pair
#define f first
#define s second

#define ttt template <typename T
ttt > using vec = vector<T>;
ttt, size_t n > using arr = array<T, n>;
using vi = vec<int>;
using vb = vec<bool>;
using vl = vec<ll>;
using vpi = vec<pi>;
#define sz(x) int((x).size())
#define all(x) begin(x), end(x)
#define rsz resize
#define pb push_back
#define eb emplace_back

#define il inline
ttt > il bool ckmin(T& x, const T& y) { return y < x ? x = y, true : false; }
ttt > il bool ckmax(T& x, const T& y) { return x < y ? x = y, true : false; }

ttt > il T safe_mid(T l, T r) { return (l & r) + ((l ^ r) >> 1); }
ttt, typename F > T find_fst(T l, T r, F f) {
  if (l > r || !f(r)) return r + 1;
  while (l < r) {
    T mid = safe_mid(l, r);
    f(mid) ? r = mid : l = mid + 1;
  }
  return l;
}
ttt, typename F > T find_lst(T l, T r, F f) {
  if (l > r || !f(l)) return l - 1;
  while (l < r) {
    T mid = safe_mid(l, r + 1);
    f(mid) ? l = mid : r = mid - 1;
  }
  return l;
}

int main() {
  cin.tie(nullptr)->sync_with_stdio(false), cin.exceptions(cin.failbit);

  int n, m, q;
  cin >> n >> m >> q;

  vec<vpi> adj(n);
  rep (m) {
    int u, v;
    cin >> u >> v, --u, --v;
    adj[u].eb(v, -1), adj[v].eb(u, -1);
  }
  F0R (i, q) {
    int u, v;
    cin >> u >> v, --u, --v;
    adj[u].eb(v, i), adj[v].eb(u, i);
  }

  vi dis(n);
  auto bfs = [&](int mid) {
    int ans = 0;
    fill(all(dis), -1), dis[0] = 0;
    queue<int> q{{0}};
    while (!q.empty()) {
      int u = q.front();
      q.pop(), ans = dis[u];
      for (auto [v, w] : adj[u])
        if (w <= mid && dis[v] == -1) dis[v] = dis[u] + 1, q.push(v);
    }
    return ans;
  };

  int i = -1, ans = bfs(i);
  while (i < q) {
    int j =
        find_fst(i, q - 1, [&](int mid) { return bfs(mid) <= (ans - 1) >> 1; });
    rep (j - i) cout << ans << " ";
    i = j, ans = bfs(i);
  }
  cout << "\n";
}

标签:return,int,题解,mid,Approximate,CF1804F,using,ttt,define
From: https://www.cnblogs.com/ClHg2/p/18046628

相关文章

  • CF1827C Palindrome Partition 题解
    CF1827CPalindromePartition题解题面题目传送门。称一个字符串是好的,当且仅当它是一个长度为偶数的回文串或由若干长度为偶数的回文串拼接而成。给定一个长度为\(n\)的字符串\(s\),求有多少\(s\)的子串是好的。$1\len\le5\cdot10^5$,\(s\)仅包含小写字母。......
  • P6185 序列 题解
    如果发现自己莫名其妙错了,可能是代码UB,还开O2!!!!!!!!!!!传送门首先,对于每个操作2,将\(u_i,v_i\)连边。连边之后每个连通块内部可以在总和不变的情况下任意改变。用并查集将每个连通块缩点,然后对于每个操作1,将\(u_i,v_i\)连边。得到的图又会分成若干个连通块。判断整个图是否可行,只......
  • [ABC238F] Two Exams 题解
    [ABC238F]TwoExams题解思路解析这题很麻烦,因为有两个维度。所以可以想到先按照第一维排序,这样就不需要考虑第二维的问题。其次再发现数据范围小,可以想到能用dp做,接下来就考虑如何dp。首先我们要知道我们遍历到了第几个公民,同时还要知道还剩下几个代表名额,同时我们还需要思......
  • P8085 [COCI2011-2012#4] KRIPTOGRAM 题解
    P8085[COCI2011-2012#4]KRIPTOGRAM题解本文原发布于2024-02-07洛谷题库P8085[COCI2011-2012#4]KRIPTOGRAM题解区,现于2024-2-29转载至博客园思路解析这道题目的主要难点在于如何判断明文中形如\(\texttt{abcb}\)的子串可以和密文\(\texttt{bcac}\)匹配,因为如果......
  • 个人题解:江苏省选 2019 第二轮
    精准预测我们首先发现每个人每个时刻只有生死,所以我们可以建一个2-sat模型。每个人对应\(T+1\)个节点,表示这个人在每个时刻的生死。那么,题目的条件可以直接在这个模型上面建图,还要注意第\(t\)秒死亡可推出第\(t+1\)秒死亡和第\(t+1\)秒存活能推出第\(t\)秒存活的两......
  • 后端项目打包相关问题解决
    在对项目进行打包后,我运行jar包发现出现下面错误:nomainmanifestattribute,in"app.jar" 在“app.jar”中没有主清单属性说明jar包里面的META-INF/MANIFEST.MF文件中没有Main-Class这个属性于是我解压jar包,到META-INF/MANIFEST.MF文件中手动添加了Main-Class: com.xxx.xx......
  • 2024年2月29号题解
    P1014[NOIP1999普及组]Cantor表解题思路和之前的蛇蝎矩阵很像,因此可以先构建一个蛇蝎矩阵因为是z形所以在每个奇数次矩阵的对角线进行交换就可以了,这样就得到了我们需要的矩阵代码实现#define_CRT_SECURE_NO_WARNINGS#include<stdio.h>#include<stdlib.h>#inclu......
  • 题解 CF1709 XOR
    *2400*dsuontree一道很好的题目思路很巧妙传送门题目大意给出一棵树,\(n\)个节点,每个节点有权值\(v\),定义一次操作为修改任意一个节点的值为任意正整数,要求最后的树不存在任意简单路径使得路径异或和为\(0\)Solution一个很常用的套路,先钦定根节点为\(1\)定义\(w......
  • CF1265E Beautiful Mirrors 题解
    CF1265EBeautifulMirrors题解题目大意题目传送门你有\(n\)个点,当你在第\(i\)个点时,有\(p_i\)的概率到达点\(i+1\),有\(1-p_i\)的概率回到点1。当到达点\(n+1\)时,游戏结束。且期望进行的游戏次数。\(1\len\le2\times10^5\)。题目分析设\(f_i\)表示到达点\(......
  • P2606 [ZJOI2010] 排列计数 题解
    题意:求有多少个排列满足:对于每一个\(2\lei\len\),\(a_i>a_{\frac{i}{2}}\)。首先我们会发现这些数之间的大小关系形成了一个完全二叉树,因为每一个\(a_i\)都必须小于\(a_{2\timesi}\)和\(a_{2\timesi+1}\)。会发现本题的方案和每个位置具体的值并没有关系,而只......