首页 > 其他分享 >Codeforces 1833E Round Dance

Codeforces 1833E Round Dance

时间:2023-06-02 20:55:08浏览次数:42  
标签:return fa Dance Codeforces cz int ufl getfa Round

看到 shortest paths 来做的,但是好像没啥关系也没啥难度。

首先能知道一个连通块肯定一次就能跳完,所以可以把连通块缩出来。
然后有一个性质,记 \(cz_i\) 为 \(i\) 连通块内点种通过已知边推出的度数为 \(1\) 的个数为 \(cz_i\),则 \(cz_i\bmod 2 = 0\)。
记点 \(i\) 通过已知边推出的度数为 \(d_i\),大致证一下,分三种情况:

  1. \(d_u = 0, d_v = 0\),个数 \(+2\)。
  2. \(d_u = 1, d_v = 1\),个数 \(-2\)。
  3. \(d_u = 0, d_v = 1\),个数不变。

对于 \(cz_i\) 对答案的贡献,分两种情况考虑:

  1. \(cz_i = 0\),则这部分肯定会产生 \(1\) 的贡献。
  2. \(cz_i > 0\),则很显然可以通过让两个度数为 \(1\) 的点相连是 \(cz_i\) 变为 \(\le cz_i\) 的任何偶数。
    则当 \(cz_i = 0\) 时,每个连通块都会产生 \(1\) 的贡献,即最大值;
    当 \(cz_i = 2\) 时,可以对于每一个 \(cz_i = 2\) 的连通块相连成一个环,所有连通块只会产生 \(1\) 的贡献,即最小值。
// lhzawa(https://www.cnblogs.com/lhzawa/)
#include<bits/stdc++.h>
using namespace std;
const int N = 2e5 + 10;
int fa[N], dz[N];
int hv[N], cz[N];
int main() {
	int Tcs;
	scanf("%d", &Tcs);
	function<void ()> solve = []() -> void {
		// printf("\n");
		int n;
		scanf("%d", &n);
		for (int i = 1; i <= n; i++) {
			fa[i] = i, dz[i] = 0;
		}
		function<int (int)> getfa = [&getfa](int u) -> int {
			return fa[u] == u ? u : (fa[u] = getfa(fa[u]));
		};
		map<pair<int, int>, bool> l;
		function<void (int, int)> add = [getfa, &l](int u, int v) -> void {
			if (! l[{u, v}]) {
				l[{u, v}] = l[{v, u}] = 1, dz[u]++, dz[v]++;
			}
			u = getfa(u), v = getfa(v);
			if (u == v) {
				return ;
			}
			fa[u] = v;
			return ;
		};
		for (int i = 1; i <= n; i++) {
			int v;
			scanf("%d", &v);
			add(i, v);
		}
		for (int i = 1; i <= n; i++) {
			hv[i] = cz[i] = 0;
		}
		for (int i = 1; i <= n; i++) {
			// printf("%d ", dz[i]);
			int f = getfa(i);
			hv[f] = 1, cz[f] += (dz[i] == 1);
		}
		// printf("\n");
		int ul = 0, ufl = 0;
		for (int i = 1; i <= n; i++) {
			if (hv[i]) {
				// printf("%d ", cz[i]);
				ul += (cz[i] > 0), ufl += (cz[i] == 0);
			}
		}
		// printf("\n");
		// printf("ul = %d, ufl = %d, ans = ", ul, ufl);
		printf("%d %d\n", (ul > 0) + ufl, ul + ufl);
		return ;
	};
	for (; Tcs; Tcs--) {
		solve();
	}
	return 0;
}

标签:return,fa,Dance,Codeforces,cz,int,ufl,getfa,Round
From: https://www.cnblogs.com/lhzawa/p/17452887.html

相关文章

  • android: workaround for slow ‘building workspace’ problem in eclipse
    Whiledevelopingforandroidoneclipse3.6ihadtheproblemthateachtimeisavedafile,eclipseblockedmeseveralsecondswith‘buildingworkspace…’.Similartothese:stackoverflow–android-compilation-is-slow-using-eclipsestackoverflow–android-......
  • codeforces Connected Components(寻找补图的连通块)
    http://codeforces.com/contest/920/problem/EE.ConnectedComponents?timelimitpertestmemorylimitpertestinputoutputn verticesand  edges.Insteadof......
  • SMU Spring 2023 Contest Round 4(第 21 届上海大学程序设计联赛 春季赛)
    A.Antiamunywantstolearnbinarysearch签到题.#include<map>#include<set>#include<cmath>#include<queue>#include<stack>#include<cstdio>#include<vector>#include<climits>#include<......
  • Codeforces 1515I - Phoenix and Diamonds(值域倍增+线段树)
    首先\(c\)很大,因此复杂度跟\(c\)有关的项肯定只能是\(\logc\)之类的。类比IOI2021dungeons的套路,我们对值域进行分层,假设\(c\in[2^{\omega-1},2^{\omega})\),考虑令重量在\(\ge2^{\omega-1}\)的物品为“重物品”,其他物品为“轻物品”,那么一个显然的性质是我们最多只......
  • SMU Spring 2023 Trial Contest Round 11
    A.TheTextSplitting题意:给出字符串长度,给出p和q两种切割方式,任选其中一种,把字符串分割输出结果。 题解:先进行判断,p和q是否能整个的分割n,利用p和q的函数关系判断(见代码),再计算有几个p几个q,再进行输出即可voidsolve(){cin>>n>>p>>q;cin>>s;if(p>......
  • surrounded-regions
    Givena2Dboardcontaining'X'and'O',captureallregionssurroundedby'X'.Aregioniscapturedbyflippingall'O'sinto'X'sinthatsurroundedregion.Forexample,XXXXXOOXXXOXXOXXAft......
  • Round-Robin轮询调度法及其实现原理
    轮询调度算法(Round-RobinScheduling)轮询调度算法的原理是每一次把来自用户的请求轮流分配给内部中的服务器,从1开始,直到N(内部服务器个数),然后重新开始循环。算法的优点是其简洁性,它无需记录当前所有连接的状态,所以它是一种无状态调度。轮询调度算法流程假设有......
  • Codeforces Beta Round #2--B题 (DP)
    题目:Theleastroundway 1000*1000的方阵,每个格子有一个非负整数,现在要从左上走到右下,每次只能向下或者向右走。目标是使得所有走的格子里的数的乘积里,末尾0的个数最少,要求输出最有解和走法。不用怎么想也知道基本是个dp了,可以发现其实只有2和5的因子是有用的,但是如果状态同时记......
  • NSSRound#11 Basic
    ez_encABAABBBAABABAABBABABAABBABAAAABBABABABAAABAAABBAABBBBABBABBABBABABABAABBAABBABAAABBAABBBABABABAAAABBAAABABAABABBABBBABBAAABBBAABABAABBAAAABBBAAAABAABBBAABBABABAABABAAAAABBBBABAABBBBAAAABBBBBAB题目提示不是baconic,那就将A转成0,B转成1,然后用工具一把梭,发现......
  • Codeforces Round 875 (Div. 2)B-D
    原题链接:https://codeforces.com/contest/1831原文:https://www.cnblogs.com/edgrass/p/17440602.html(B)Arraymerging主体思想是找到ab数组的最长相同字串(c中操作可实现连续)1#include<bits/stdc++.h>2usingnamespacestd;3intmain(){4intt;5cin>>......