首页 > 其他分享 >洛谷P10179 题解

洛谷P10179 题解

时间:2024-02-20 09:25:54浏览次数:24  
标签:洛谷 首领 int 题解 void 集团 fa P10179 一个点

题意简述

给定 \(n\) 个点,要求构造出一棵树,同时有 \(m\) 个事件,第 \(i\) 个事件要求 \(u_i\) 和 \(v_i\) 用两条树边连接,即当中相隔一个点。若存在构造方案,输出 Yes 并输出其中一种方案,否则输出 No

思维路径

首先简化问题,假如我们想让一堆点互相相隔一个点,我们的做法。考虑菊花图(如下图),所有绿色的点都恰好相隔一个点(中间的黑点),可以满足条件。

接下去考虑继续扩展,假如有很多像绿点这样的集团,都有求互相相隔一个点,我们可以对于每个集团选择一个首领,把首领串成一条链,剩下的集团连相邻的首领上。如图所示,同一种颜色位同一个集团。

请注意,对于上面这种情况我的构造方案是将集团 \(i\) 的点连在 \(i+1\) 上,对于最后一个集团连在它的前一个上。

但是这与题目并非完全一致。我们将集团的定义改为对于任意集团内的点 \(u\),必定存在集团内另一个点 \(v\) 要求与 \(u\) 相隔为 1 个点。

此时就需要证明,之前的构造对于这个定义能够得到正确答案。

  • 假设当前点 \(v\) 是首领,那么点 \(u\) 连在旁边的首领上,可以满足条件。
  • 假设当前点 \(v\) 不是首领,已经连在了旁边的首领上,那么点 \(u\) 也连在旁边的首领上,可以满足条件。

综上所述之前的构造方案是可以在这个定义的前提下得到正确答案的。

实现细节

寻找集团的方式可以用并查集,首领就自动为并查集最终找到的祖先即可。

假若最终只剩下一个集团就无解。

具体实现可以参考 AC 代码。

AC 代码

#include<bits/stdc++.h>
using namespace std;
const int N=300009;
int T;
int n,m,nC;
int fa[N],cn[N],t[N];

void init(){
	cin>>T;
}

void input(){
	cin>>n>>m;
}

int findfa(int u){
	if(fa[u]==u) return u;
	else return fa[u]=findfa(fa[u]);
}

void add(int u,int v){
	int fu=findfa(u);
	int fv=findfa(v);
	if(fu==fv) return;
	fa[fu]=fv;
}

void solve(){
	for(int i=1;i<=n;i++) fa[i]=i;
	for(int i=1;i<=m;i++){
		int u,v;
		cin>>u>>v;
		add(u,v);
	} 
	nC=0;
	for(int i=1;i<=n;i++){
		if(fa[i]==i){
			cn[++nC]=i;
			t[cn[nC-1]]=i;//记录相邻的下一个点
		}
	}
	if(nC==1){
		cout<<"No\n";
		return;
	}
	cout<<"Yes\n";
	t[cn[nC]]=cn[nC-1];//最后一个点连到上一个点
	for(int i=1;i<nC;i++){//连首领
		cout<<cn[i]<<" "<<cn[i+1]<<"\n";
	}
	for(int i=1;i<=n;i++){//连其他点
		if(fa[i]==i) continue;
		cout<<i<<" "<<t[findfa(i)]<<"\n";
	}
}

int main(){
	init();
	while(T--){
		input();
		solve();
	}
	return 0;
}

后记

和出题人给出的构造好像有些许不同,但本质是一样的。

标签:洛谷,首领,int,题解,void,集团,fa,P10179,一个点
From: https://www.cnblogs.com/lemon-cyy/p/18022369

相关文章

  • 程序设计天梯赛个人题解 L2-047-2 锦标赛
    题目分析综合题意,将最后一场比赛视为顶层,第一轮比赛视为第一层,则有:下层每场比赛选出一个胜者,每两个下层的胜者间举行本层的一次比赛,显然这是一个二叉树。考虑还原建立每场比赛的树。由于最后一层的比赛是$2^k$个选手参加,故这是个完美二叉树,使用完全二叉树的数组储存方式,则标号......
  • 洛谷-P3380/LibreOJ-106/BZOJ-3196题解
    题意简述给定一个数列,支持以下操作:查询\(k\)在区间内的排名(区间内比\(k\)小的数的个数\(+1\))查询区间内排名为\(k\)的值修改某一位值上的数值查询\(k\)在区间内的前驱(前驱定义为严格小于\(k\),且最大的数,若不存在输出-2147483647)查询\(k\)在区间内的......
  • U41492 树上数颜色 题解
    U41492树上数颜色题目描述给一棵根为1的树,每次询问子树颜色种类数输入格式第一行一个整数n,表示树的结点数接下来n-1行,每行一条边接下来一行n个数,表示每个结点的颜色c[i]接下来一个数m,表示询问数接下来m行表示询问的子树输出格式对于每个询问,输出该子树颜色数输入输出......
  • P2524 Uim的情人节礼物•其之弐 题解
    题目描述前传:详见洛谷P2525Uim成功地按照顺序将礼物送到了 N 个妹子的手里并维持她们的和谐。现在Uim现在想知道,他最终选择的顺序是所有给 N 个妹子送礼顺序中,字典序第几小的。送礼顺序可以看作1,2,⋯,N 的一个排列。输入格式第一行一个整数N,表示有 N 个数。第二......
  • 洛谷题单指南-递推与递归-P1990 覆盖墙壁
    原题链接:https://www.luogu.com.cn/problem/P1990题意解读:用两种可旋转的形状铺满N*2的区域,求方案数,可以使用递推。解题思路:步骤1、设f[i]表示铺满i*2的区域的方案数根据要求,i*2区域最后一列有4种可能的铺法:如果采用图1铺法,则有f[i]=f[i-1]如果采用图2铺法,则有f[i]=f......
  • P3411 序列变换 题解
    自己做不出来,看现在题解区的题解讲的都不咋清楚。懂了之后来为后人铺路。而且我的马蜂比较好看题目传送门我能看懂这道题,主要是依靠了这篇题解的帮助。首先我们只关注数的相对关系,所以可以离散化。注意到值域\(10^6\),用数组离散化。这道题可以用贪心做。(有一些定义先往下看)......
  • P5914 MOS 题解
    一道练习贪心证明的好题。绝大多数题解只是点出了以下结论:要么最快的带最慢的;要么最慢的带次慢的。并没有给出证明。我就补上这个证明。为了证明这个贪心结论,我们先证明几个引理。引理一:每次将火把带回来的,一定是对岸最快的。引理一证明:如果回来的不是对岸最快的,让对岸最......
  • 洛谷题单指南-递推与递归-P1164 小A点菜
    原题链接:https://www.luogu.com.cn/problem/P1164题意解读:要求正好把钱花完,并且统计不同的点菜方案数,本质上是一个背包问题,给定背包体积,要求物品正好装满背包的方案数。解题思路:1、最直观的解法是暴搜:DFS枚举每一道菜,有点或者不点两种选择,并且累加上已花费的总金额递归前,判断......
  • CF167B题解
    CF167B这里更容易进入且有翻译题意给定初始背包容量\(k\),要进行\(n\)场比赛,每场比赛有\(p_i\%\)的概率能够胜利,赢的一场比赛能获得一个奖励——当\(a_i=-1\)时获得一个体积为\(1\)的奖品,或者当\(a_i>0\)时给背包增加\(a_i\)容量,求所有比赛结束后至少赢得\(......
  • 理想的正方形——题解
    题目描述一看正方形,得,二维数组,单调队列。单调队列可以将一个区间最大值存储,所以只需要根据给定的正方形长度先横着推一遍,再竖着推一遍,将正方形中的最大值和最小值都储存在正方形右下角方格,最后遍历即可。先以行储存以k为长度的最大/小值;再以剩下k-m横向长度的最值向下扩展k个......