首页 > 其他分享 >CF300B Coach 题解

CF300B Coach 题解

时间:2023-11-13 15:15:58浏览次数:39  
标签:Coach int 题解 查集 CF300B fa MAXN find

闲话

调了好一会,甚至还重构了一次代码才对,但是还是很喜欢并查集,并查集可爱捏。


题意省流

$n$ 个学生分成 $3$ 人一组,要满足 $m$ 个条件,每个条件给出两个数 $x,y$,要求 $x$ 和 $y$ 必须在一个组里。

正文

要使学生三人一组,一眼使用并查集。

首先考虑无解(输出 $-1$ )的情况:

  • 给出的限制条件中有大于 $3$ 个人组队的情况。
  • 有一人或两人落单。

第二种情况的数据:

6 4
1 2
3 4
5 6

此时没有能够凑出 $3$ 人一队的方案,输出 $-1$。

对于合法的情况可以分三种情况:

  1. 组中已经有三人,可以直接成组。
  2. 组中有两人,需要找落单一人。
  3. 仅有一人,可以与两人组成组或另找两个单人成组。

贴码

没有优化,人傻常数大,但是在 $3\leq n\leq 48$ 的情况下其实不是很要紧。

其实是因为没有精神再去打更好的解法了。

#include<bits/stdc++.h>
#define MAXN 10010
using namespace std;
int n,m,fa[MAXN],ans,ton[MAXN];
int akali[MAXN],num[MAXN],cnt;
bool vis[MAXN],Vis[MAXN];
queue<int> q[MAXN];
int find(int x){
	if(x==fa[x]) return x;
	return fa[x]=find(fa[x]);
}
int main(){
	ios::sync_with_stdio(0);
	cin>>n>>m;
	for(int i=1;i<=n;i++) fa[i]=i;
	for(int i=1,u,v;i<=m;i++){
		cin>>u>>v;
		int fau=find(u),fav=find(v);
		fa[fau]=fav;
	}
	for(int i=1;i<=n;i++) ton[find(i)]++;
	for(int i=1;i<=n;i++){
		if(ton[fa[i]]>=4){
			cout<<-1;
			return 0;
		}
		q[fa[i]].push(i);
		if(!Vis[fa[i]]){
			Vis[fa[i]]=1;
			num[++cnt]=fa[i];
		}
		akali[fa[i]]++;
	}
	for(int i=1;i<=cnt;i++){/*处理 2+1 的情况*/
		if(akali[num[i]]==2){
			for(int j=1;j<=cnt;j++){
				if(i==j) continue;
				if(akali[num[j]]==1){
					akali[num[j]]=0;
					q[num[i]].push(num[j]);
					fa[num[j]]=num[i];
					break;
				}
			}
		}
	}
	for(int i=1;i<=cnt;i++){/*处理 1+1+1 的情况*/
		if(akali[num[i]]==1){
			for(int j=i+1;j<=cnt;j++){
				if(akali[num[j]]==1){
					akali[num[j]]=0;
					q[num[i]].push(num[j]);
					fa[num[j]]=num[i];
					for(int k=1+j;k<=cnt;k++){
						if(akali[num[k]]==1){
							akali[num[k]]=0;
							q[num[i]].push(num[k]);
							fa[num[k]]=num[i];
							break;
						}
					}
					break;
				}
			}
			akali[num[i]]=3;
		}
	}
	for(int i=1;i<=n;i++){
		if(q[fa[i]].size()!=3){/*若有不能成组的则无解*/
			cout<<-1;
			return 0;
		}
	}
	for(int i=1;i<=n;i++){
		if(!vis[fa[i]]){
			vis[fa[i]]=1;
			while(!q[fa[i]].empty()){
				cout<<q[fa[i]].front()<<" "; q[fa[i]].pop();
			}
			cout<<"\n";
		}
	}
	return 0;
}

标签:Coach,int,题解,查集,CF300B,fa,MAXN,find
From: https://www.cnblogs.com/AlpacaKing-presidential-palace/p/17829167.html

相关文章

  • 【题解 P8476】 惊蛰
    「GLR-R3」惊蛰题目背景  「微雨众卉新,一雷惊蛰始」  中午,休息室,阿绫肩膀上。  “我有一个愿望,参加全国音乐祭,获奖,和阿绫一起,摆脱这训练的苦海。”  “为热爱而到来,为抽身而努力……吗”。  正午的阳光渗过窗帘,抚上困倦的人儿的脸颊。天依的左手悄悄搭上阿绫怀里......
  • NOJ题解
    NOJ题解30-40素数埃氏筛,欧拉筛都可可变参数累加/平均用给出的库函数即可基思数根据题意模拟#include<stdio.h>#definelllonglongllnum[102];inlineboolIsKeith(lln){inttot=0,t=0;lls=n;while(s){num[++tot]=s%10......
  • 问题解答:SAP OData V2 和 V4 里针对日期类型的字段进行过滤操作(filter)的正确语法试
    我的知识星球里有朋友咨询一个问题:我测试了一个S/4HANAcloud的purchaseorder的API,这个是ODATAV4格式的。在对CreationDate做filter后运行有报错Invalidparametertypeusedwithfunction'eq'.对datetime字段做filter,一直搞不清楚格式。请帮忙看一下。本文就安排这......
  • [题解] P6569 [NOI Online #3 提高组] 魔法值
    P6569[NOIOnline#3提高组]魔法值不放简要题意了,题面写的很简要。看到数据范围自然可以想到矩阵快速幂优化。但乘法对异或没有分配律。所以直接拆位,把异或变成加法对二取模就有分配律了。还有一个优化就是提前预处理出矩阵的2的幂次方,然后询问时直接二进制分解乘起来就行......
  • ARC119F 题解
    前言ARC119F好厉害,是没见过的自动机DP。正文[1]分析主要分析一下为什么这么写。[2]状态设计[3]自动机状态转移感觉状态设计中最难的就是如何处理带\(O\)的。见参考资料。[4]代码还没写。写ing这是自动机的初始化(有点麻烦)。intto[Kind][2][2]={{{2,0},{8,0......
  • ABC328F题解
    原题链接洛谷题面提交记录闲话赛场就做了这道和A,喜提\(625\)大分。带权并查集练手题,有点像银河英雄传说。题目大意存在一个长度为\(N\)的数列\(X\),给定\(Q\)个三元组\((a_i,b_i,d_i)\),定义一个好集合为集合\(S\subseteq\{1,2,\dots,Q\}\),使得所有\(x\inS\)满......
  • 题解:[春季测试 2023] 幂次
    题解:[春季测试2023]幂次给定\(n,k\),求有多少个整数\(i\in[1,n]\),满足\(i=a^b(a,b\inN^+,b\geqk)\)算法一\(k\ge3:\)发现只需要筛到1e6就没有贡献了,加上\(set\)暴力判重即可。\(k=2:\)发现有\(\sqrt{n}\)个完全平方数,考虑如何避免算重它们。考虑完全平......
  • Tenzing and Random Operations CF1842G 题解
    设\(m\)次选的位置分别为\(b_{1\simm}\)。于是答案为\(\mathbbE(\prod\limits_{i=1}^{n}(a_i+\sum\limits_{j=1}^{m}[b_j\lei]\cdotv))=\frac{S}{n^m}\)。首先考虑期望很难做,希望将期望转化为概率形式,发现这样有点困难。再考虑因为所有方案等概率,将求期望转化......
  • P2687 [USACO4.3] 逢低吸纳 题解
    双倍经验分析这是一道求最长下降子序列的题目,且要统计方案,但是会有重复情况,例如以下的的数据,44223我们可以选择\(1,2\),\(1,2\),\(1,4\)这几天来购买,但是\(1,2\)和\(1,3\)本质上是一样的,所以只算一种。根据上面的说明,我们可以得出:当\(dp_j+1=dp_i\)......
  • [题解] P9838 挑战 NPC IV
    P9838挑战NPCIV定义\(f(x)=1+\log_2\operatorname{lowbit}(x)\)。定义一个\(1\simn\)的排列\(p\)的权值是\(\sum_{l=1}^n\sum_{r=l}^n\sum_{i\in[l,r]}f(p_i)。\)求所有\(1\simn\)的排列中权值第\(k\)小的排列的权值,对\(998244353\)取模。......