训练19 加权并查集

2023-10-29

做事情要有始有终。昨天下午暑期集训画上了句号,我整个人也就随着懈怠了下来。这篇题解是我最后的惯性了吧。之前拉下的题我是不打算继续写了。
下一阶段依然是刷题,准备回洛谷去。白天学习正经东西,晚上研究副业。


Virtual Friends

A Bug’s Life

Zjnu Stadium


Virtual Friends

Problem Description
These days, you can do all sorts of things online. For example, you can use various websites to make virtual friends. For some people, growing their social network (their friends, their friends’ friends, their friends’ friends’ friends, and so on), has become an addictive hobby. Just as some people collect stamps, other people collect virtual friends.

Your task is to observe the interactions on such a website and keep track of the size of each person’s network.

Assume that every friendship is mutual. If Fred is Barney’s friend, then Barney is also Fred’s friend.
Input
Input file contains multiple test cases.
The first line of each case indicates the number of test friendship nest.
each friendship nest begins with a line containing an integer F, the number of friendships formed in this frindship nest, which is no more than 100 000. Each of the following F lines contains the names of two people who have just become friends, separated by a space. A name is a string of 1 to 20 letters (uppercase or lowercase).
Output
Whenever a friendship is formed, print a line containing one integer, the number of people in the social network of the two people who have just become friends.
Sample Input
1
3
Fred Barney
Barney Betty
Betty Wilma
Sample Output
2
3
4
题目大意给你建立的关系,询问每次建立关系后这个并查集的人数。
算是一道很基础的模板题,在结构体内多定义一个变量记录自己的儿子有几个(包括自己)。合并的时候把这个量给祖宗加上就行。另外用map存储字符串就不说了。
这个题有个很坑的点,从来没见过要写while(cin>>T) while(T–)

//You has the final say in what kind of life you want.
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
#define MAX 200000 +10
using namespace std;
map<string,int>name;
int cnt;
struct People
{
	int fa;
	int q;
}people[MAX];

int findfa(int x)
{
	if(people[x].fa==-1)
		return x;
	people[x].fa=findfa(people[x].fa);
	return people[x].fa;
}

void Initial()
{
	for(int i=0;i<MAX;i++)
	{
		people[i].fa=-1;
		people[i].q=1;
	}
	name.clear();
	cnt=0;
	return;
}

int merge(int a,int b)
{
	int afa=findfa(a);
	int bfa=findfa(b);
	if(afa==bfa)
		return people[afa].q;
	people[afa].q+=people[bfa].q;
	people[bfa].fa=afa;
	return people[afa].q;		
}

int main()
{
	ios::sync_with_stdio(false);
	int n,T;
	string a,b;
	while(cin>>T)
	{
		while(T--)
		{
			Initial();
			cin>>n;			
			for(int i=0;i<n;i++)
			{
				cin>>a>>b;
				if(name[a]==0)
					name[a]=++cnt;
				if(name[b]==0)
					name[b]=++cnt;
				printf("%d\n",merge(name[a],name[b]));
			} 
		}
		
	}		
	return 0;
}

A Bug’s Life

Problem Description
Background
Professor Hopper is researching the sexual behavior of a rare species of bugs. He assumes that they feature two different genders and that they only interact with bugs of the opposite gender. In his experiment, individual bugs and their interactions were easy to identify, because numbers were printed on their backs.

Problem
Given a list of bug interactions, decide whether the experiment supports his assumption of two genders with no homosexual bugs or if it contains some bug interactions that falsify it.
Input
The first line of the input contains the number of scenarios. Each scenario starts with one line giving the number of bugs (at least one, and up to 2000) and the number of interactions (up to 1000000) separated by a single space. In the following lines, each interaction is given in the form of two distinct bug numbers separated by a single space. Bugs are numbered consecutively starting from one.
Output
The output for every scenario is a line containing “Scenario #i:”, where i is the number of the scenario starting at 1, followed by one line saying either “No suspicious bugs found!” if the experiment is consistent with his assumption about the bugs’ sexual behavior, or “Suspicious bugs found!” if Professor Hopper’s assumption is definitely wrong.
Sample Input
2
3 3
1 2
2 3
1 3
4 2
1 2
3 4
Sample Output
Scenario #1:
Suspicious bugs found!

Scenario #2:
No suspicious bugs found!
题目大意有n条虫子,m次交配关系,每次都要是不同性别的。问是否存在同性恋。
网上说用二分图匹配法,我早忘了这玩意是啥了。后来又想起来老师上课讲过一种题就是这样的,具体做法是,用一个数组a记录某一条虫子x的异性配偶编号y,然后每当有一条虫子z和x交配的时候就把z和y放到一个并查集里。
这个方法比我的简单不知多少了。
我用了类似食物链那个题的做法,将他们都放到一个并查集里,在子节点记录边的权重,找规律。1代表和父节点性别相反,0代表相同,各种亦或。然后向上查找祖宗的时候用的循环,顺便处理边的权重。这样效率上可能比递归慢点,因为递归的话能把父节点一并处理。但是循环我认为比较好写。
然后这个题我T了好几次,因为寻找父节点的函数没有-1的直接返回值,导致将某个点的-1赋值成了自己,进入了死循环。以后写程序没把握就一步步输出来看看。
然后T完后终于。。WA了。没记错的话应该是merge某个变量名字写错了。主要还是问题没有想清楚。日了狗了。

#include<iostream>
#include<cstdio>
#define MAX 2000+10
using namespace std;
int n;
struct Bug
{
	int fa;
	int gen;
}bug[MAX];
void Initial()
{
	for(int i=0;i<MAX;i++)
	{
		bug[i].fa=-1;
		bug[i].gen=0;
	}
	return;
}
int findfa(int x)
{
	if(bug[x].fa==-1)
		return x;
	int y=x;
	while(bug[y].fa!=-1)
	{
		y=bug[y].fa;
		bug[x].gen=bug[x].gen^bug[y].gen;
	}
	bug[x].fa=y;
	
	return y;
}
bool merge(int a,int b)
{
	int afa=findfa(a);
	int bfa=findfa(b);
	if(afa==bfa&&!(bug[a].gen^bug[b].gen))
		return 0;
	if(afa!=bfa)
	{
		bug[bfa].fa=afa;
		bug[bfa].gen=(bug[b].gen==bug[a].gen?1:0);
	}
	return 1;
}

int main()
{
	int T,m;
	int a,b;
	bool flag;
	scanf("%d",&T);
	for(int cnt=1;cnt<=T;cnt++)
	{
		Initial();
		flag=1;
		scanf("%d%d",&n,&m);
		for(int i=0;i<m;i++)
		{
			scanf("%d%d",&a,&b);
			if(!flag)
				continue;
			flag=merge(a,b);
//			for(int i=1;i<=n;i++)	cout<<bug[i].fa<<", ";cout<<endl;
//			for(int i=1;i<=n;i++)	cout<<bug[i].gen<<",  ";cout<<endl;
		}
		printf("Scenario #%d:\n",cnt);
		if(flag)
			printf("No suspicious bugs found!\n");
		else printf("Suspicious bugs found!\n");
		printf("\n");
	}
	return 0;
}

Zjnu Stadium

Font Size: ← →
Problem Description
In 12th Zhejiang College Students Games 2007, there was a new stadium built in Zhejiang Normal University. It was a modern stadium which could hold thousands of people. The audience Seats made a circle. The total number of columns were 300 numbered 1–300, counted clockwise, we assume the number of rows were infinite.
These days, Busoniya want to hold a large-scale theatrical performance in this stadium. There will be N people go there numbered 1–N. Busoniya has Reserved several seats. To make it funny, he makes M requests for these seats: A B X, which means people numbered B must seat clockwise X distance from people numbered A. For example: A is in column 4th and X is 2, then B must in column 6th (6=4+2).
Now your task is to judge weather the request is correct or not. The rule of your judgement is easy: when a new request has conflicts against the foregoing ones then we define it as incorrect, otherwise it is correct. Please find out all the incorrect requests and count them as R.
Input
There are many test cases:
For every case:
The first line has two integer N(1<=N<=50,000), M(0<=M<=100,000),separated by a space.
Then M lines follow, each line has 3 integer A(1<=A<=N), B(1<=B<=N), X(0<=X<300) (A!=B), separated by a space.

Output
For every case:
Output R, represents the number of incorrect request.
Sample Input
10 10
1 2 150
3 4 200
1 5 270
2 6 200
6 5 80
4 7 150
8 9 100
4 8 50
1 7 100
9 2 100
Sample Output
2
问题大意有个总长为600圈,告诉你a在b顺时针方向相隔多少。问你有没有矛盾的说法。
并查集加一个边权记录与父节点相隔多少,把距离什么的公式写对然后记得对600取余就行。寻找祖宗的时候这个距离要一并处理,永远记录的是与父节点顺时针方向的距离。然后如果两个在一个并查集里,通过与父节点距离判断他俩是不是如题目所说的相距d。
距离公式没想清楚,merge函数某个数少了个负号,WA了一次。避免方法还是以后复杂一点的程序数出来看一下。

#include<iostream>
#include<cstdio>
#define MAX 50000+10
using namespace std;
int n;
struct People
{
	int fa;
	int dis;
}people[MAX];

void Initial()
{
	for(int i=0;i<MAX;i++)
		people[i].fa=-1,people[i].dis=0;
}

int findfa(int x)
{
	if(people[x].fa==-1)
		return x;
	int y=x;
	while(people[y].fa!=-1)
	{
		y=people[y].fa;
		people[x].dis=(people[x].dis+people[y].dis+600)%600;
	}
	people[x].fa=y;
	return y;
}


bool merge(int a,int b,int d)
{
	int afa=findfa(a);
	int bfa=findfa(b);
	if(afa==bfa)
	{
		if((people[b].dis-people[a].dis+600)%600==d)
			return 1;
		else return 0;
	}
	people[bfa].fa=afa;
	people[bfa].dis=(-people[b].dis+d+people[a].dis+600)%600;
	return 1;
}

int main()
{
	int m,a,b,d,ans;
	while(~scanf("%d%d",&n,&m))
	{
		Initial();
		ans=0;
		while(m--)
		{
			scanf("%d%d%d",&a,&b,&d);
			if(!merge(a,b,d))
				++ans;
//			for(int i=1;i<=n;i++)	cout<<people[i].fa<<",";cout<<endl;
//			for(int i=1;i<=n;i++)cout<<people[i].dis<<",";cout<<endl;		
		}
		printf("%d\n",ans);
	}
	return 0;
}


最后一篇题解写的略有含糊。算是给暑假集训画个句号吧。二十多天不算长,也算过得充实了。以后的路长的很,可能这个开头是我最轻松的时候吧。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

训练19 加权并查集 的相关文章

  • C++学习(四八四)anaconda常用命令

    安装tensorflow pip install tensorflow gpu 2 3 0 i https pypi tuna tsinghua edu cn simple pip install tensorflow 安装最新版tenso
  • POJ 2689 Prime Distance(素数区间筛法--经典题)

    大致题意 给定 L R 区间 找出区间内的每个素数 数据范围 1 lt L lt R lt 2 147 483 647 R L lt 1 000 000 R的数值太大 所以不能直接筛 0 R 的 要空间和时间优化 用到区间筛法 另外注意不能
  • 新型的编程语言:eC

    http www cnbeta com articles 61048 htm eC 是一位加拿大人jerome历时十二年开发的一门编译型编程语言 拥有C 项目的性能和Java的跨平台性以及Python的方便性 目前eC拥有自己的IDE 专用
  • android 优秀控件以及开源项目

    原文地址为http www trinea cn Android android open source projects view 作者Trinea 主要介绍那些不错个性化的View 包括ListView ActionBar Menu Vi
  • 设计模式课件

    设计模式 创建型设计模式的分类 定义 结构型设计模式的分类 定义 行为型设计模式的分类 定义 设计模式的分类 在23种设计模式中 每一种属于哪一种的设计模式 设计模式的应用场景 设计模式的图形 考察较少 创建型设计模式的分类 定义 中英文的
  • 【踩雷小记】pytorch用transforms同时旋转图像和标签

    对于transforms中带有概率参数的函数 例如 transforms RandomHorizontalFlip p 0 5 依概率p进行水平翻转 transforms RandomVerticalFlip p 0 5 依概率p进行垂直翻
  • linux I2C之RTC8025、fm24cl16

    说明 主设备I2C 0挂载两个从设备fm24cl16铁电和RTC rx8025t 内核 linux3 10 32 平台 nuc972 1 板级文件修改 arch arm much nuc970 dev c 1 1 i2c 0的platfor
  • HTML-网页-3D旋转相册-创意相册

    HTML 网页 3D旋转相册 代码
  • vue3跨页面锚点定位/页面跳转后使用锚点定位(vue2类似)

    实现效果 跨页面跳转后定位到页面相应位置 这个需求常在官网底部导航栏开发中遇到 vue3 ts开发官网底部导航为例 我的底部导航封装为了一个组件 所以会涉及到父子组件传参 不清楚的伙伴可以去查一下相关资料 注意 这里的跨页面锚点定位分为从一
  • DBUS接口

    我用 CSDN 这个app发现了有技术含量的博客 小伙伴们求同去 DBUS基础知识 非常全面 一起来围观吧 https blog csdn net f110300641 article details 106823611 utm sourc
  • UVa1347 Tour

    题目描述 这道题我想了很久都没有想到 看了lrj的题解才会做 首先可以想到转化成两个人向右走 关键在于状态的设计 设 f i j f i j 为走完了前 max i j max i j 的点 且两个人分别在i j的位置 且 i gt j i
  • LeetCode 336. Palindrome Pairs(回文对)

    原题网址 https leetcode com problems palindrome pairs Given a list of unique words Find all pairs of distinct indices i j in
  • Python爬虫完整代码模版

    以下是一个简单的Python爬虫完整代码模板 用于演示如何使用requests库和BeautifulSoup库爬取网页内容 import requests from bs4 import BeautifulSoup Step 1 发起HTT
  • Warning[Pa050]: non-native end of line sequence detected (this diagnostic is only issued once)

    今天在用IAR软件 给Zigbee程序写注释时 出现了这么一个警告 Warning Pa050 non native end of line sequence detected this diagnostic is only issued
  • OpenGL GLFW入门篇 - 画凸多边形

    效果图 主体代码 void DrawPolygon void glPushMatrix glLoadIdentity glTranslatef 0 0 0 0 0 f 蓝色 glColor3f 0 f 0 f 1 f glBegin GL
  • 递归函数斐波那契数列

    F 0 0 F 1 1 F n F n 1 F n 2 n 2 n N def fibonacci n 求斐波那契数列的第n个数字的值 if n 0 return 0 elif n 1 return 1 else return fibona
  • PHP表单(get,post)提交方式

    PHP 表单处理 PHP 超全局变量 GET 和 POST 用于收集表单数据 form data GET 是通过 URL 参数传递到当前脚本的变量数组 POST 是通过 HTTP POST 传递到当前脚本的变量数组 有一点很重要的事情值得注
  • 【CocosCreator入门】CocosCreator组件

    Cocos Creator是一款流行的游戏开发引擎 具有丰富的组件和工具 其中TiledMap组件可以帮助开发者快速创建 加载和渲染地图 目录 一 组件介绍 二 组件属性 三 脚本控制 3 1加载地图 3 2渲染地图 四 详细说明 五 关闭

随机推荐

  • Mac下Android源码(AOSP)编译环境搭建方法

    一 编译源码的背景环境 Android源码编译有什么困难 AOSP 非常庞大 需要下载 但是他是Google家的 和大陆开发者之间隔着一个GFW 官方文档 推荐使用Ubuntu 14 04进行编译 我用的是MacOS 官网也给了Mac下的编
  • 【学习笔记38】JavaScript中的本地存储

    一 localStorage 浏览器的本地存储 永久存储 打开浏览器存储上之后 关闭浏览器 信息还在 语法 window localStorage setItem key value 注意 value的值必须为字符串 key的书写符合见名知
  • 海量数据处理:MapReduce算法

    MapReduce算法是一种用于处理海量数据的分布式计算模型 它通过将数据分解成多个小任务 并在分布式计算集群中并行执行这些任务 从而实现高效的数据处理 本文将介绍MapReduce算法的原理和实现 并提供相应的源代码示例 MapReduc
  • 计算机金额函数,电脑计算机编程入门教程自学:原生JavaScript实现金额大写转换函数...

    1 function transform tranvalue 2 try 3 var i 1 4 var dw2 new Array 万 亿 大单位 5 var dw1 new Array 拾 佰 仟 小单位 6 var dw new Ar
  • nacos的安装、启动、控制台的打开

    官网 https nacos io zh cn docs quick start html 1 下载nacos包 目前稳定版本1 4 1 方式一 在github上对应下载其中一个即可 https github com alibaba nac
  • Amazon Lightsail——兼具亚马逊云科技的强大功能与 VPS 的简易性

    对于开发者而言 当你想构建系统架构时 你的面前就出现了两种选择 选择一 花时间去亲手挑选每个亚马逊云科技组件 云服务器 存储 IP 地址等 然后自己组装起来 选择二是只需要一个预先配置且预先组装的系统 就可以运行自己的 Web 应用程序 而
  • java 企业工程管理系统软件源码 自主研发 工程行业适用

    工程项目管理软件 工程项目管理系统 对建设工程项目管理组织建设 项目策划决策 规划设计 施工建设到竣工交付 总结评估 运维运营 全过程 全方位的对项目进行综合管理 工程项目各模块及其功能点清单 一 系统管理 1 数据字典 实现对数据字典标签
  • 我的漫长python之路

    1 为什么我用一个remove却删了两个数
  • 区间预测

    区间预测 MATLAB实现QRFR随机森林分位数回归多输入单输出区间预测 目录 区间预测 MATLAB实现QRFR随机森林分位数回归多输入单输出区间预测 效果一览 基本介绍 模型描述 程序设计 参考资料 效果一览 基本介绍 MATLAB实现
  • 什么是gradle

    目录 一 什么是Gradle 二 Gradle的基本组成 1 Project与Task 2 插件 3 Gradle配置文件 4 构建脚本 三 常见配置 1 依赖第三方库 2 导入本地jar包 3 依赖其它模块 4 构建输出为aar文件 5
  • day03 homework

    统计正数和负数的个数然后计算这些数的平均值 编写一个程序来读入不指定个数的整数 然后决定已经读取的整数中有多少个正数和多少个负数并计算这些输入值 不统计0 的总和 最终得出他们的平均值 这个程序以输入值0来结束 使用浮点数显示这个平均值 执
  • VC++公安指纹识别系统

    论文编号 VC 039 论文题目 公安指纹识别系统 开发语言 VC 包括内容 论文 可执行程序 源码 外文翻译 程序操作演示录像 数 据 库 无 论文字数 39000字以上
  • 多系统U盘启动盘的制作,成功启动win8PE,ubuntu,deepin2013,deepin2014,以及通过U盘启动电脑已装系统。

    以前的用U盘装系统都是用ultraISO 直接制作启动盘 有的时候一连着好几天都得捣鼓着装系统 今天是windows 明天是ubuntu 后天就可能是其它linux发行版了 很不方便 所以就想利用一个U盘做一个多系统的启动盘 经过N天不断的
  • 【python基础知识】6.布尔值和四种语句(break、continue、pass、else)

    文章目录 前言 用数据做判断 布尔值 两个数值做比较 直接用数值做运算 布尔值之间的运算 四种新的语句 break语句 continue语句 pass语句 else语句 循环小练习 前言 Hi 你来了 上一关我们学习了for循环和while
  • U盘安装系统----缺少所需的CD/DVD驱动器设备驱动程序

    用U盘启动盘安装系统 首先用软碟通制作启动盘 惠普电脑安装开机的时候 按F9 选择USB启动即可 如果不行的話 开机时按F2或者F10 进入高级设置 英文好像是advanced 选择first什么的 再选择带usb的那个选项即可然后按F10
  • 6-1 JAVA成绩比较 (10分) java pta

    本题要求实现Student类 该类实现Comparable接口 用于计算两个同学的JAVA成绩差 其中一个同学的数据已经输入 只需要从键盘输入第二个同学的信息 只有姓名和JAVA成绩两项 最终返回成绩差 裁判测试程序样例 在这里给出该类被调
  • 攻防世界(pwn)echo_back writeup

    checksec 保护全开 漏洞 利用要点 泄露关键信息 pie开启 gt 泄露elf base 泄露libc base 攻击scanf 修改 IO buf base扩大可输入字符串数 进一步修改 IO buf base与 IO buf e
  • Netty4框架的初步使用

    Netty4框架的初步使用 Netty4的基本概念网上有很多 这里就不多说 这仅仅只是一个小例子 功能模块分三部分 1 Handler 消息处理 2 Client 客户端 3 Server 服务端 结构目录 代码如下 公用的Handler
  • xss-labs/level10

    我们试试看输入以下代码 从界面上看确实只有一个输出点 但是不要被事物的表面所蒙蔽 我们的去更深层的源代码部分详究 从源代码层面上去看输出点 也只有一个输出点 不会吧 判断失误啦 应该不会 因为我从源代码看到了三个表单标签 而且还是设置隐藏属
  • 训练19 加权并查集

    做事情要有始有终 昨天下午暑期集训画上了句号 我整个人也就随着懈怠了下来 这篇题解是我最后的惯性了吧 之前拉下的题我是不打算继续写了 下一阶段依然是刷题 准备回洛谷去 白天学习正经东西 晚上研究副业 Virtual Friends A Bu