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

CF1804F Approximate Diameter 题解

时间:2023-12-16 15:23:58浏览次数:25  
标签:ch int 题解 Approximate read que CF1804F define dis

题目链接

点击打开链接

题目解法

很有意思的题,但不难

首先一个显然的结论是:算着边的加入,直径长度递减
第一眼看到误差范围是 2 倍,可以想到二分
可以观察到如果取答案为 \(\frac{n}{2}\) 可以覆盖到 \(\frac{n}{4}\)(上下取整不重要),那这样每次可以把值域范围缩小 4 倍,然后只要二分直径在这个范围内的操作区间即可

但现在有问题是无法求出一个图的直径
继续考虑估测
有一个结论是:图上任意一点到其他点的最远距离 \(\ge \frac{diameter}{2}\)
这不难证明,具体来说,在直径上的点显然是满足结论的,不在直径上的点需要先到直径上,才能到端点,显然也是满足结论的

然后就稍微变化一下上面的二分区间就可以做到 \(O(n\log^2n)\) 的复杂度

#include <bits/stdc++.h>
#define F(i,x,y) for(int i=(x);i<=(y);i++)
#define DF(i,x,y) for(int i=(x);i>=(y);i--)
#define ms(x,y) memset(x,y,sizeof(x))
#define SZ(x) (int)x.size()-1
#define pb push_back
#define x first
#define y second
using namespace std;
typedef long long LL;
typedef unsigned long long ull;
typedef pair<int,int> pii;
template<typename T> void chkmax(T &x,T y){ x=max(x,y);}
template<typename T> void chkmin(T &x,T y){ x=min(x,y);}
inline int read(){
    int FF=0,RR=1;
    char ch=getchar();
    for(;!isdigit(ch);ch=getchar()) if(ch=='-') RR=-1;
    for(;isdigit(ch);ch=getchar()) FF=(FF<<1)+(FF<<3)+ch-48;
    return FF*RR;
}
const int N=100100,M=100100;
int n,m,q,ans[M],dis[N];
pii E[M<<1];
queue<int> que;
vector<int> G[N];
void add_edge(int x,int y){ G[x].pb(y),G[y].pb(x);}
int get_dia(int opt){
    F(i,1,n) G[i].clear(),dis[i]=-1;
    F(i,1,m) add_edge(E[i].x,E[i].y);
    F(i,1,opt) add_edge(E[i+m].x,E[i+m].y);
    que.push(1),dis[1]=0;
    while(!que.empty()){
        int u=que.front();que.pop();
        for(int v:G[u]) if(dis[v]==-1) dis[v]=dis[u]+1,que.push(v);
    }
    int ret=0;
    F(i,1,n) chkmax(ret,dis[i]);return ret;
}
int main(){
    n=read(),m=read(),q=read();
    F(i,1,m) E[i]={read(),read()};
    F(i,1,q) E[i+m]={read(),read()};
    int x=get_dia(0),L=0;
    while(true){
        int lo=L-1,hi=q+1;
        while(lo<hi-1){
            int mid=(lo+hi)/2,dia=get_dia(mid);
            if(dia>=(x+1)/2) lo=mid;
            else hi=mid;
        }
        F(i,L,lo) ans[i]=x;
        L=lo+1;
        if(!x) break;
        x/=2;
    }
    F(i,0,q) printf("%d ",ans[i]);puts("");
    fprintf(stderr,"%d ms\n",int(1e3*clock()/CLOCKS_PER_SEC));
    return 0;
}

标签:ch,int,题解,Approximate,read,que,CF1804F,define,dis
From: https://www.cnblogs.com/Farmer-djx/p/17904872.html

相关文章

  • [ARC124C] LCM of GCDs 题解
    题目跳转Fake_Solution前言[warning]:本题解的做法是错法,但是正确概率贼高。离谱的是正确率还可以叠加。正解是记搜,时间复杂度可以证明。正解看文末。思考众所周知一个公式:\[a\timesb=\operatorname{lcm}(a,b)\times\gcd(a,b)\]如果你不知道——自证吧,不难。于是,移一......
  • CF327C Magic Five 题解
    题目传送门前置知识等比数列求和公式|乘法逆元解法设\(lena\)表示\(a\)的长度。首先,若一个数能被\(5\)整除,则该数的末尾一定为\(0\)或\(5\)。故考虑枚举\(a\)中所有的\(0\)和\(5\)的下标,设此下标后面有\(x\)个数字,由于\(s\)是由\(a\)复制\(k\)遍形......
  • gamble 题解报告
    #Galble题解简要题意:  给定一个数$n$AB两人赌博,每次你作为第三者下注任意整数$x$元,A赢则获得$x$元,否则亏损$x$元。任何一个人赢$n$次立刻结束游戏。你需要每次基于现在的情况,计算下的赌注,以使得在整个赌博的全过程,如果A胜利则获得$2^{2n-1}$元,否则亏损这么......
  • 题解 CF1887E【Good Colorings】
    萌萌交互题。对网格图进行二分图建模,左部\(n\)个点表示每一行,右部\(n\)个点表示每一列。若格子\((i,j)\)被染成\(c\)色,就连接\((L_i,R_j,c)\)的边。由抽屉原理易证,在初始局面中至少有一个各边颜色均不同的偶环。获胜条件相当于存在一个各边颜色均不同的四元环。讨论......
  • 洛谷P1824 进击的奶牛 题解 二分答案
    题目链接:https://www.luogu.com.cn/problem/P1824题目大意:本题相当于在\(n\)个数中选\(c\)个数,使得这\(c\)个数中相差最小的两个数之差尽可能地大。解题思路:我们首先可以给\(a_1\sima_n\)从小到大排一下序(这里有点贪心的思想,你会发现很多涉及贪心的问题在排序之后解......
  • ABC332G Not Too Many Balls 题解
    第\(i\)种球有\(a_i\)个,共\(n\)种。第\(i\)种箱子最多共装\(b_i\)个球。共\(m\)种。第\(i\)种球在第\(j\)种箱子里至多放\(ij\)个。问所有箱子放的球数最多是多少。\(1\leqn\leq500,1\leqm\leq5e5,0\leqa_i,b_i\leq1e12\)。很容易建出网络流模型。......
  • CF1784C Monsters (hard version) 题解 线段树
    题目链接:https://codeforces.com/problemset/problem/1784/C题目大意:你面前有\(n\)只怪兽,每只怪兽都有一个初始血量,你可以进行两类操作:操作1:选择任意一个血量大于\(0\)的怪兽,并将它的血量降低\(1\);操作2:将所有存活的怪物的血量各自减去\(1\),如果存在怪物的血量恰好降为......
  • PTA-2023第十三次练习题目题解
    PTA-2023第十三次练习题目题解以下代码已做防抄袭处理,切勿抄袭。注意:手机端因为屏幕限制,代码会有(不希望的)换行。解决方案:1.建议使用电脑端打开。2.点击代码进入全屏观看。6-25实验9_5_反向打印字符串思路就是每次先找到字符串的最后一位,然后输出这一位,输出之后将这一位改为‘......
  • P8818 [CSP-S 2022] 策略游戏 题解
    P8818[CSP-S2022]策略游戏题解题目链接P8818[CSP-S2022]策略游戏简化题意小\(A\)先在\(a[l1,r1]\)中选择一个数\(x\),小\(B\)再在\(b[l2,r2]\)中选择一个数\(y\),最后的分数就是\(x\timesy\)。小\(A\)想让分数尽可能地大,而小\(B\)则想让分数尽可能地小......
  • 【问题解决】unable to do port forwarding: socat not found
    问题复现前阵子应公司要求做华为云平台的调研,写了一篇文档包含将华为云CCE下载kuberctl配置及使用kubectl转发流量到本地的操作。今天一早上同事就发来一个错误界面,说是Java远程调试转发过来的端口出现问题,如下图:处理思路最初以为是容器镜像未安装socat所致,安装重新打镜像后......