【并查集】家谱

洛谷【P2814】
给出充足的父子关系,请你编写程序找到某个人的最早的祖先。

Input

输入由多行组成,首先是一系列有关父子关系的描述,其中每一组父子关系中父亲只有一行,儿子可能有若干行,用#name的形式描写一组父子关系中的父亲的名字,用+name的形式描写一组父子关系中的儿子的名字;接下来用?name的形式表示要求该人的最早的祖先;最后用单独的一个$表示文件结束。

Output

按照输入文件的要求顺序,求出每一个要找祖先的人的祖先,格式:本人的名字+一个空格+祖先的名字+回车。


不管,我就是不用map!!!校网TLE是因为评测机卡!!!
将字符串以序号,然后普通并查集。

#include<cstdio>
#include<iostream>
#include<cstring>
#include<string>
using namespace std;
int t,ff,z,f[50001];
char c;
string ss,s;
int find(int d){
	if(f[d]!=d) f[d]=find(f[d]);
	return f[d];
}
int fa(string ls){          //寻找ls是第几个
	int kk=ss.find(ls);
	if(kk<0){  //如果没有,存下来。
		ss+=ls;
		++t;
		f[t]=t;
	}
	else return kk/6+1;   //不然输出他是第几个(因为名字长度固定为6位)
	return t;
}
int main(){
	c=getchar();
	while(c!='$'){
		while(c!='#'&&c!='+'&&c!='?'&&c!='$') 
		  c=getchar();
		if(c=='$') break;
		if(c=='#'){
			cin>>s;
			ff=fa(s);
		}
		else{
			cin>>s;
			z=fa(s);
			if(c=='+') f[find(z)]=find(ff);   //合并
			else if(c=='?') cout<<s<<' '<<ss.substr(find(f[z])*6-6,6)<<endl;  //输出 
		}
		c=getchar(); 
	}
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值