首页 > 其他分享 >CF1583E Moment of Bloom 题解

CF1583E Moment of Bloom 题解

时间:2024-03-09 19:45:09浏览次数:23  
标签:dth return int 题解 printf Moment fnd lca Bloom

题意:

给定一张 \(n\) 个点 \(m\) 条边无向连通图,以及 \(q\) 个点对 \((a,b)\),出事每条边权值为 \(0\)。对于每个点对我们需要找一条从一个点到另一个点的简单路径,将所有边的权值加一。要求构造一种方案使得每条边权值都是偶数。如果不行,输出最少还要几个点对才能满足要求。

\(n,m \le 10^5\)。

思路:

这个条件不难联想到欧拉回路,我们尝试构造一个图 \(G'\) 使得这 \(q\) 个点对是这张图的所有边。

如果这张图存在欧拉回路,则我们只用在回路最后一条边反向走一遍便能满足要求。回到原图,随便一棵生成树上走两点路径即可。

如果不存在欧拉回路,说明一定有奇点,这就会导致有的边边权是奇数。具体而言,我们记录每个点所有相邻边的边权和的奇偶性。显然一个点对只会改变两个端点,所以如果不存在欧拉回路,则必然不成立。需要再加上奇点个数除以二个。

然后就没了。

点击查看代码
#include <iostream>
#include <cstdio>
#include <vector>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 3e5 + 5;

int n, m, q;
vector<int> e[N], E[N];
int cnt[N] = {0};
int a[N] = {0}, b[N] = {0};

int p[N] = {0};
int fnd(int x) {
	if (p[x] == x)
		return x;
	return p[x] = fnd(p[x]);
}
void unn(int x, int y) {
	p[fnd(x)] = fnd(y);
}

int pr[N] = {0}, dth[N] = {0};

void srh(int x, int Pr, int d) {
	dth[x] = d, pr[x] = Pr;
	for (auto i: E[x])
		if (i != Pr)
			srh(i, x, d + 1);
}

int fnd_lca(int x, int y) {
	if (x == y)
		return x;
	if (dth[x] < dth[y])
		swap(x, y);
	return fnd_lca(pr[x], y);
}

void fnd_prx(int x, int anc) {
	if (x == anc)
		return;
	printf("%d ", x);
	fnd_prx(pr[x], anc);
}

void fnd_suf(int x, int anc) {
	if (x == anc)
		return;
	fnd_suf(pr[x], anc);
	printf("%d ", x);
}

void fnd_pth(int x, int y) {
	int lca = fnd_lca(x, y);
	printf("%d\n", dth[x] + dth[y] - 2 * dth[lca] + 1);
	fnd_prx(x, lca);
	printf("%d ", lca);
	fnd_suf(y, lca);
	printf("\n");
}

int main() {
	scanf("%d%d", &n, &m);
	for (int i = 1, u, v; i <= m; i++) {
		scanf("%d%d", &u, &v);
		e[u].push_back(v);
		e[v].push_back(u);
	}
	scanf("%d", &q);
	for (int i = 1; i <= q; i++) {
		scanf("%d%d", &a[i], &b[i]);
		cnt[a[i]]++, cnt[b[i]]++;
	}
	int odd = 0;
	for (int i = 1; i <= n; i++)
		odd += cnt[i] % 2;
	if (odd > 0) {
		printf("No\n%d\n", odd / 2);
		return 0;
	}
	
	for (int i = 1; i <= n; i++)
		p[i] = i;
	for (int i = 1; i <= n; i++)
		for (auto j: e[i])
			if (fnd(i) != fnd(j)) {
				unn(i, j);
				E[i].push_back(j);
				E[j].push_back(i);
			}
	srh(1, 1, 1);
	printf("YES\n");
	for (int i = 1; i <= q; i++) 
		fnd_pth(a[i], b[i]);
	return 0; 
}

标签:dth,return,int,题解,printf,Moment,fnd,lca,Bloom
From: https://www.cnblogs.com/rlc202204/p/18063190

相关文章

  • CF1634E Fair Share 题解
    题意:给定\(m\)个长度为偶数的数组,\(L,R\)是初始为空的两个多重集。将每个数组恰好一半的数放入\(L\),另一半放入\(R\),要求最后\(L=R\),要求构造方案或判断无解。\(m\le10^5,\sumn\le10^5\)。思路:首先我们不难想到,对于同一个数组内相同的值,可以成双除去,所以我们可以......
  • Interval GCD 题解
    题目描述给定一个长度为\(\largen\)的数组\(\largea\),以及\(\largem\)条指令(\(n\leq5\times10^5,m\leq10^5\)),每条指令可能是以下两种之一:“\(\large\operatorname{C\l\r\d}\)”,表示把\(\largea[l],a[l+1],…,a[r]\)都加上\(\larged\)。“\(\large\operatorn......
  • CF1264D2 Beautiful Bracket Sequence (hard version) 题解
    括号深度的本质,其实就是删除若干个字符以后使得左边一半全是(,右边一半全是),最终(的个数的最大值。那么就一定存在一个位置使得在这个位置以及之前的字符中(的个数等于这个字符后)的个数。考虑枚举这个位置,记它左边的(的个数为\(a\)、?的个数为\(x\),右边的)的个数......
  • [CF696B] Puzzles 题解
    首先很好想到要用树形\(dp\)。然后设\(dp_i\)为遍历到第\(i\)个点的期望时间,\(sz_i\)代表\(i\)的子树大小。发现有转移方程:\[dp_i=dp_{fa_i}+1+\sum\limits_{j\infa_i且j\nei}sz_j\timesq\]其中\(q\)为一个常数,代表在排列中\(j\)在\(i\)前的概率。很容易发......
  • 无聊的数列[题解]
    无聊的数列[link1][link2]题目大意给定一个数列\(A\)有两种操作:将数列中\(A_i\)(\(L\leqi\leqR\))加上一个等差数列(首项D公差K)查询数列中第P位数区间加上一个等差数列可以用差分来解决例原序列:000000差分序列:000000等差序列:13579(首项1......
  • 课堂练习 最大值 原题链接+题解
    题目可以去我的洛谷题库看:https://www.luogu.com.cn/problem/U412348(带数据,真难出)题解考虑两种解题方式。由于题目范围较小,可以check+暴力,如果范围大一点,可以check+二分答案。先讲check函数,小学四年级数学书说了,这种问题也被它叫做“铺地砖”问题,计算剪出的正方形数量的方......
  • 一本通 1270 混合背包 题解
    是在hydro上做的,墙裂推荐hydro的一本通题库!链接是:https://hydro.ac/d/ybttk/p/T1270。分析一下,可以分类讨论,处理的时候,零一背包(\(p_i=1\))一个,完全背包(\(p_i=0\))一个,多重背包(\(p_i>1\))一个,状态转移方程不用列的,直接去抄模板就可以啦~代码是这样的捏:#include<bits/st......
  • P6583 回首过去 题解
    P6583回首过去题解题目传送门好题。更新(2023-12-05):把代码和$\LaTeX$改得更好看了。题意简述给定正整数$n$,求出有序整数对$(x,y)$的个数,满足$1\lex,y\len$且$\dfracxy$可以表示为十进制有限小数。$1\len\le10^{12}$。前置知识数论分块解法Subtas......
  • CF1846D Rudolph and Christmas Tree 题解
    因为\(n\)个三角形有重叠部分,所以我们可以倒序处理每个三角形,并对其进行分类讨论:若当前三角形编号为\(n\),则直接将总面积加上\(\dfrac{d\timesh}{2}\)。否则,再次分出两种情况:若当前三角形的\(y_i+h>y_{i+1}\)(即编号为\(i,i+1\)的三角形有重叠),则如下图所示:......
  • CF387B George and Round 题解
    考虑采用双指针法解决此题。首先需要对\(a,b\)数组排序,并且维护两个指针\(l,r\),分别指向\(a,b\)两个数组中的元素。接着循环移动\(r\)指针,每次都尝试匹配\(a_l\)和\(b_r\):若\(a_l\leb_r\),则说明\(a_l=b_r\)或可以采用减少\(b_r\)的方式使\(a_l=b_r\),这......