首页 > 其他分享 >CF1827E Bus Routes 题解

CF1827E Bus Routes 题解

时间:2024-04-05 23:35:02浏览次数:28  
标签:ch return int 题解 节点 fa Bus Routes mx

这是一道拥有 *3400 标签的题目。

首先很显然可以将题意中的条件转化为任意两个度数为一的节点都能通过不超过两条路径互相到达。接下来随便取一个度数大于一的节点作为根,如果 \(n=2\) 直接判掉即可。

考虑两个叶子节点能互相到达一定需要满足什么条件,发现两个点通过一条路径能到达的最浅的节点一定是祖先关系,于是所有叶子节点能到达的最浅的节点就一定在一条链上。

然后发现答案为 YES 当且仅当每个叶子节点都能通过一条路径到达这条链上深度最深的节点,直接判就做完了。时间复杂度 \(\mathcal O(n\log n)\)。

参考代码:

#include<bits/stdc++.h>
#define mxn 500003
#define pb push_back
#define rep(i,a,b) for(int i=a;i<=b;++i)
#define rept(i,a,b) for(int i=a;i<b;++i)
#define drep(i,a,b) for(int i=a;i>=b;--i)
using namespace std;
inline int read(){
	int x=0;char ch=getchar();
	while(!isdigit(ch))ch=getchar();
	while(isdigit(ch))x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
	return x;
}
int t,n,m,rt,ps,mx,pt,tot,d[mxn],dfn[mxn],rs[mxn],f[mxn][20];
vector<int>g[mxn],e[mxn];
void dfs(int x,int fa){
	dfn[x]=++tot;
	d[x]=d[fa]+1,f[x][0]=fa;
	rept(i,1,19)f[x][i]=f[f[x][i-1]][i-1];
	for(int i:g[x])if(i!=fa){
		dfs(i,x);
	}
	rs[x]=tot;
}
int lca(int x,int y){
	if(d[x]<d[y])swap(x,y);
	drep(i,18,0)if(d[f[x][i]]>=d[y])x=f[x][i];
	if(x==y)return x;
	drep(i,18,0)if(f[x][i]!=f[y][i])x=f[x][i],y=f[y][i];
	return f[x][0];
}
inline bool in(int x,int y){
	return dfn[x]<=dfn[y]&&dfn[y]<=rs[x];
}
signed main(){
	t=read();
	while(t--){
		n=read(),m=read();
		rep(i,1,n)g[i].clear(),e[i].clear();
		for(int i=1,x,y;i<n;++i){
			x=read(),y=read();
			g[x].pb(y),g[y].pb(x);
		}
		for(int i=0,x,y;i<m;++i){
			x=read(),y=read();
			if(x==y)continue;
			if(g[x].size()==1)e[x].pb(y);
			if(g[y].size()==1)e[y].pb(x);
		}
		if(n==2){
			puts(e[1].size()?"YES":"NO\n1 2");
			continue;
		}
		rep(i,1,n){
			if(g[i].size()!=1)rt=i;
			else if(e[i].empty()){
				printf("NO\n%d %d\n",i,i==1?n:1);
				goto next;
			}
		}
		tot=0;
		dfs(rt,0);
		mx=pt=0;
		rep(i,1,n)if(g[i].size()==1){
			ps=0;
			for(int j:e[i]){
				int x=lca(i,j);
				if(!ps||d[x]<d[ps])ps=x;
			}
			if(!mx||d[ps]>d[mx])mx=ps,pt=i;
		}
		rep(i,1,n)if(g[i].size()==1){
			for(int j:e[i]){
				int x=lca(i,j);
				if(in(x,mx)&&(in(mx,i)||in(mx,j)))goto nxt;
			}
			printf("NO\n%d %d\n",i,pt);
			goto next;
			nxt:;
		}
		puts("YES"); 
		next:;
	}
	return 0;
}

标签:ch,return,int,题解,节点,fa,Bus,Routes,mx
From: https://www.cnblogs.com/zifanoi/p/18116886

相关文章

  • PLC通过Modbus转Profinet网关连接压力计的配置方法
    由于现场控制器无法正常连接压力计,咨询了解后我们通过使用Modbus转Profinet网关把连接压力计和控制顺利连接并通讯上,实现Modbus协议与Profinet协议之间的数据转换和传输,使得压力计能够无缝集成到基于Profinet的工业自动化系统中。Modbus转Profinet网关接压力计的配置方法主要包......
  • [题解]ABC346 补题C~E
    想起上次的ABC346没打,刚才虚拟参赛打了A~D,E题思路有,但是实现方式没选好导致WA了,没能在赛时做出来。写下题解记录一下~C-Σ用求和公式先把\(1\simk\)的和求出来:\(\frac{k(k+1)}{2}\),然后对于\(A\)数组中的元素依次减去就行(注意相同元素不能减\(2\)次)点击查看代码#include<b......
  • P9902 『PG2』模拟最大流 题解
    首先最大流等于最小割,然后就能很容易地想到一个状压dp做法:记\(f_{i,s}\)表示使得前\(i\)个点中,最后\(k\)个点与点\(1\)的联通情况为\(s\)的最小代价。然后考虑下一个点是否联通直接转移即可,然后就做完了。时间复杂度\(\mathcalO(n2^k)\)。参考代码:#include<bits/s......
  • P9058 [Ynoi2004] rpmtdq 题解
    Description给定一棵有边权的无根树,需要回答一些询问。定义\(\texttt{dist(i,j)}\)代表树上点\(i\)和点\(j\)之间的距离。对于每一组询问,会给出\(l,r\),你需要输出\(\min(\texttt{dist(i,j)})\)其中\(l\leqi<j\leqr\)。\(n\leq2\times10^5\),\(q\leq10^6\),\(1\l......
  • 二叉树计算【华为OD机试JAVA&Python&C++&JS题解】
    一.题目-二叉树计算给出一个二叉树如下图所示:6/79\/-26请由该二叉树生成一个新的二叉树,它满足其树中的每个节点将包含原始树中的左子树和右子树的和。20(7-2+9+6)/\-26\/......
  • 学生重新排队【华为OD机试JAVA&Python&C++&JS题解】
    一.题目-学生重新排队n个学生排成一排,学生编号分别是1到n,n为3的整倍数。老师随机抽签决定将所有学生分成m个3人的小组,n=3*m为了便于同组学生交流,老师决定将小组成员安排到一起,也就是同组成员彼此相连,同组任意两个成员输入描述:之间无其它组的成员。因此老师决定调整队伍,......
  • 题解 CF1942F【Farmer John's Favorite Function】
    萌萌F题,上大分。首先,如下定义\(g(i)\):\(g(1)=\lfloor\sqrt{a_1}\rfloor\);对于所有\(i>1\),\(g(i)=\lfloor\sqrt{g(i-1)+a_i}\rfloor\)。也就是将\(f(i)\)的每一步运算后都向下取整。注意到\(\lfloorf(i)\rfloor=g(i)\)恒成立,于是我们只需要转而求每次修改后\(g(n......
  • P9870 [NOIP2023] 双序列拓展 题解
    题意:称某个序列\(B=\{b_1,b_2,\cdots,b_n\}\)是另一个序列\(A=\{a_1,a_2,\cdots,a_m\}\)的拓展当且仅当存在正整数序列\(L=\{l_1,l_2,\cdots,l_m\}\),将\(a_i\)替换为\(l_i\)个\(a_i\)后得到序列\(B\)。例如,\(\{1,3,3,3,2,2,2\}\)是\(\{1,3,3,2\}\)的拓展,......
  • CF1530G 题解
    考虑对操作进行转换。假设\(a_i\)为第\(i\)个\(1\)前面的\(0\)的个数。则操作可以进行如下转换:转换1:选择一个长度为\(k+1\)的子区间\(a_{l~l+k}\)。我们先把\(a_{l+1~l+k-1}\)翻转,然后更改\(a_l\)和\(a_{l+k}\)使得\(a_l+a_{l+k}\)不......
  • 【蓝桥杯选拔赛真题56】C++求位数 第十四届蓝桥杯青少年创意编程大赛 算法思维 C++编
    目录C++求位数一、题目要求1、编程实现2、输入输出二、算法分析三、程序编写四、程序说明五、运行结果六、考点分析七、推荐资料C++求位数第十四届蓝桥杯青少年创意编程大赛C++选拔赛真题一、题目要求1、编程实现给定一个正整数N(1<N<10^8),输出N为几位数2、......