IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 刷题记录:牛客NC15976小C的周末 -> 正文阅读

[C++知识库]刷题记录:牛客NC15976小C的周末

传送门:牛客

题目描述:

愉快的周末到了,小C和他的N-1个朋友买了M个游戏,游戏编号从1~M。每个游戏都是多人游戏,他们打算周末一起打游戏。
小C的每个朋友都决定好了要玩哪一款游戏(会有一组人打同一款游戏),并且每人手上都有一台游戏机,这种游戏机可以通过特定的游戏机连接线连接起来。
但是,他们面临着一个问题:目前没有一个朋友的游戏机是互相连接的。所以它们必须用可用的游戏机连接线连接起来。小C决定依次使用第 i 条连接线把他的朋友 ui 和 vi 的游戏机连接起来。也就是说,假设有Q条连接线,小C只能先使用第一条,然后使用第二条,然后使用第三条。。。最后使用第Q条。
一个游戏能开始的条件是所有玩这个游戏的朋友的游戏机都被连接起来(如果不是直接连接的话,那么就必须存在一条连接它们的路径)。他们希望尽快开始比赛。
在每个游戏中,找出在添加了第几条连接线之后能开始游戏。如果在一个游戏中只有一个人玩,则输出0(因为他立马可以开始游戏)。如果不存在,则输出-1
输入:
5 2 4
1 2 2 2 1
1 2 
2 3
1 5
4 5
输出:
3
4

首先读完题我们应该就可以看出来这是一道并查集的题目,并且显然的我们脑中应该会有这样的一个想法:每一次加入连线时,我们就将两个并查集合并,并且更新大的并查集中的每一个游戏的参与人数,判断是否满足条件,满足输出即可

经过分析之后我们会发现这一种做法是可行的,但是因为游戏的数量M和N太大,并且每一个人又只能有一个喜欢的游戏,如果我们开数组的话空间会被大量浪费,并且会导致MLE,此时的解决办法是离散化,但是对于离散化我们往往会有一种比较偷懒的一种解决方案,那就是使用我们的map(在这道题中我们准备开二维的map).

因为我们需要遍历map中的数据,因此我们还需要学习迭代器的知识(有点像C语言中的指针??)

对于map,我们的迭代器为map<int,int>::iterator [name]然后在for中使用

for(it = map.begin();it!=map.end;it++)

在for循环中,我们可以采用简便方法遍历auto it : [name]

在迭代器中,指针的第一个参数first代表map中的第一个值,second代表第二个值

下面是具体的代码部分(包含了迭代器的两种写法):

#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <string.h>
#include <stack>
#include <deque>
using namespace std;
typedef long long ll;
#define inf 0x3f3f3f3f
#define root 1,n,1
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
inline ll read() {
	ll x=0,w=1;char ch=getchar();
	for(;ch>'9'||ch<'0';ch=getchar()) if(ch=='-') w=-1;
	for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0';
	return x*w;
}
#define maxn 1000000
#define ll_maxn 0x3f3f3f3f3f3f3f3f
const double eps=1e-8;
int n,m,q;int fa[maxn];
map<int,int>x[100005];
int ans[maxn];int cnt[maxn];
int find(int a) {
	if(a==fa[a]) return a;
	else return fa[a]=find(fa[a]);
}
map<int,int>::iterator it;
int main() {
	while(scanf("%d%d%d",&n,&m,&q)!=EOF) {		
		memset(ans,0,sizeof(ans));
		for(int i=1;i<=n;i++) x[i].clear();
		memset(cnt,0,sizeof(cnt));
		for(int i=1;i<=n;i++) fa[i]=i;
		int num;
		for(int i=1;i<=n;i++) {
			num=read();
			cnt[num]++;
			x[i][num]++;
		}
		int u,v;
		for(int i=1;i<=q;i++) {
			u=read();v=read();
			int uu=find(u),vv=find(v);
			if(uu==vv) continue;
			if(x[uu].size()>x[vv].size()) {
				swap(u,v);
				swap(uu,vv);
			}
			fa[uu]=vv;
//			for(auto it : x[uu]) {//第一种写法
//				x[vv][it.first]+=it.second;
//				if(x[vv][it.first]==cnt[it.first]&&ans[it.first]==0) {
//					ans[it.first]=i;
//				}
//			}	
			for(it=x[uu].begin();it!=x[uu].end();it++) {//第二种写法
				x[vv][it->first]+=it->second;
				if(x[vv][it->first]==cnt[it->first]&&ans[it->first]==0) {
					ans[it->first]=i;
				}
			}
		}
		for(int i=1;i<=m;i++){
			if(cnt[i]==1) printf("0\n");
			else if(ans[i]==0) printf("-1\n");
			else printf("%d\n",ans[i]);
		} 
	}
	
	return 0;
}
  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-10-08 20:22:12  更:2022-10-08 20:25:43 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/19 5:22:07-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码