HDU 3172 Virtual Friends 并与正确集中检查 -秩

ll T;

while(~scanf("%d",&T)){

while(T--) {

= = ...

思路:

用秩合并,看了题解才发现 if(fx == fy)要输出当前集合的秩而不是0。。。

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <string.h>
#include <vector>
#include <map>
#include <queue>
#include <math.h>
#include <string>
#include <set>
using namespace std;
#define mod 1000000007
#define ll int
#define N 100100
ll r[N], f[N];
ll find(ll x){return x==f[x]?x:f[x] = find(f[x]);}
ll Union(ll x, ll y){
	ll fx = find(x), fy = find(y);
	if(fx==fy)return r[fx];
	if(r[fx]>r[fy])
		swap(fx,fy);
	f[fx] = fy;
	r[fy] += r[fx];
	return r[fy];
}
ll n;
void init(){
	for(ll i = 0; i < N; i++) r[i] = 1;
	for(ll i = 0; i < N; i++) f[i] = i;
}
#define Word_Len 50500
#define Sigma_size 95

struct Trie{
	ll ch[Word_Len][Sigma_size];	 //Word_Len是字典树的节点数 若都是小写字母Sigma_size=26
	ll Have_word[Word_Len];		 //这个节点下有几个单词
	ll val[Word_Len];				 // 这个节点附带的信息。初始化为0表示这个节点不存在单词,所以节点带的信息必须!=0
	ll sz ;						 //当前节点数
	ll pre[Word_Len];
	char he[Word_Len];
	ll Newnode(){memset(ch[sz], 0, sizeof(ch[sz])); val[sz]=Have_word[sz]=0; return sz++;}
	void init()							 //初始化字典树
	{ sz = 0; Newnode();}//初始化
	ll idx(char c){return c-32;}	 //字符串编号

	ll insert(char *s){	 //把v数字加给 s单词最后一个字母
		ll u = 0, len = strlen(s);
		for(ll i = 0; i < len; i++){
			ll c = idx(s[i]);
			if(!ch[u][c])		     //节点不存在就新建后附加
			{
				he[sz] = s[i];
				val[sz] = val[u]+1;
				pre[sz] = u;
				ch[u][c] = Newnode();
			}
			u = ch[u][c];
			Have_word[u]++;
		}			//如今的u就是这个单词的最后一个位置
		return u;
	}
	ll find_word(char *s){
		ll u = 0, len = strlen(s);
		for(ll i = 0; i < len; i++){
			ll c = idx(s[i]);
			if(!ch[u][c])return 0;		//节点不存在
			u = ch[u][c];
		}
		return Have_word[u];
	}
	void Have_name(char *s, ll now){
		ll len = val[now];
		s[len--] = 0;
		ll cc = now;
		while(cc)
		{
			s[len--] = he[cc];
			cc = pre[cc];
		}
	}
};
Trie ac;
char a[1005], b[1005];
int main(){
	ll T;
	while(~scanf("%d",&T)){
		while(T--) {
			cin>>n;
			init();
			ac.init();
			while(n--)
			{
				cin>>a>>b;
				ll u, v;
				u = ac.insert(a);
				v = ac.insert(b);
				cout<<Union(u,v)<<endl;
			}
		}
	}
	return 0;
}

版权声明:本文博客原创文章。博客,未经同意,不得转载。

时间: 2024-11-15 23:06:23

HDU 3172 Virtual Friends 并与正确集中检查 -秩的相关文章

HDU 3172 Virtual Friends 带权并查集 -秩

ll T; while(~scanf("%d",&T)){ while(T--) { = = ... 思路: 用秩合并,看了题解才发现 if(fx == fy)要输出当前集合的秩而不是0... #include <cstdio> #include <iostream> #include <algorithm> #include <string.h> #include <vector> #include <map&

hdu 3172 Virtual Friends (并查集 + 字典树)

题目: 链接:点击打开链接 题意: 输入n,给出n行数据,每行有两个字符串,输出关系网络中朋友的个数,n行. 思路: 代码: #include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> using namespace std; const int N = 22; const int M = 200020; struct node { int c; node *chil

HDU 3172 Virtual Friends(带权并查集)

题目地址:HDU 3172 带权并查集水题.每次合并的时候维护一下权值.注意坑爹的输入.. 代码如下: #include <iostream> #include <cstdio> #include <string> #include <cstring> #include <stdlib.h> #include <math.h> #include <ctype.h> #include <queue> #inclu

HDU 3172 Virtual Friends (map+并查集)

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), h

hdu 3172 Virtual Friends

原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=3172 并查集的运用... 1 #include<algorithm> 2 #include<iostream> 3 #include<cstdlib> 4 #include<cstdio> 5 #include<map> 6 using std::map; 7 using std::string; 8 const int Max_N = 100010

hdu 3172 Virtual Friends (映射并查集)

Virtual Friends Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 5491    Accepted Submission(s): 1519 Problem Description These days, you can do all sorts of things online. For example, you can u

hdu 3172 Virtual Friends(并查集)

题目比较简单,但作为长久不写题之后的热身题还是不错的. 统计每组朋友的朋友圈的大小. 如果a和b是朋友,这个朋友圈的大小为2,如果b和c也是朋友,那么a和c也是朋友,此时这个朋友圈的大小为3. 输入t,表示接下来有t组数据. 每组数据有n组朋友关系. 接下来n行,每行一组朋友关系,然后输出这组朋友的朋友圈大小,即有多少朋友. 然后又是t组数据……(这点好坑)重复上述输入,直到数据结束. 因为最多有10^5个人,那么如果用线性字符串数组保存人名,肯定超时得不要不要的,所以要用map(每次操作时间复

BZOJ 3362 POJ 1984 Navigation Nightmare 并与正确集中检查

标题效果:一些养殖场是由一些南北或东西向的道路互连. 镶上在不断的过程中会问两个农场是什么曼哈顿的距离,假设现在是不是通信.那么输出-1. 思维:并与正确集中检查,f[i]点i至father[i]距离,为了维持两个值,一个是东西向的距离.一个是南北向的距离,由于以后更新的时候要用到.在合并的时候有些特殊.如今有一条边(x->y),设fx为x的根.fy为y的根,那么如今知道f到fx的距离.y到fy的距离.还知道x到y的距离,设fx到fy的距离为dis,则dis + f[y] = f[x] + ed

HDU 并查集 - 3172 Virtual Friends

并查集题目,并的意思就是将两个不同类别的集合合并到一起,类似于两棵树合并:查的意思就是找到这个点所属集合的根节点.基本上并查集题目都是在大体架构上面加一些东西即可.并查集代码模板在这里点击打开链接. 这一题为了找到输入的两个人组成的社交网络人数,也就是统计这两个人与前面的人组成的集合中有多少元素.我们加一个辅助数组sum,当两个集合并时,我们将父节点对应下标的sum值加上子节点的sum值,表达这个集合有多少元素. #include<stdio.h> #include<iostream&g