首页 > 其他分享 >hdu 3172(并查集+hash)

hdu 3172(并查集+hash)

时间:2023-05-29 19:35:22浏览次数:54  
标签:hdu set hash int fy include num maxn 3172


解题思路:典型的并查集,只是每个人的名字要转换成数字,可以用map,也可以用字典树,我最开始用的字典树结果爆内存了。。


爆内存:

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;

const int maxn = 200000;
int n,fa[maxn],trie[maxn][52],cnt,id[2000000],num;
int tot[maxn];
char str[2][20];

void init()
{
	for(int i = 0; i <= 2*n; i++)
	{
		fa[i] = i;
		tot[i] = 1;
	}
	memset(id,-1,sizeof(id));
	memset(trie,-1,sizeof(trie));
	cnt = num = 0;
}

int insert(char *s)
{
	int p = 0,idx;
	while(*s != 0)
	{
		if(*s >= 'A' && *s <= 'Z') idx = *s - 'A' + 26;
		else idx = *s - 'a';
		if(trie[p][idx] == -1)
			trie[p][idx] = ++cnt;
		p = trie[p][idx];
		s++;
	}
	if(id[p] == -1)
		id[p] = ++num;
	return id[p];
}

int find(int x)
{
	if(fa[x] == x) return x;
	return fa[x] = find(fa[x]);
}

int main()
{
	int t,x,y,fx,fy;
	scanf("%d",&t);
	while(t--)
	{
		scanf("%d",&n);
		init();
		for(int i = 1; i <= n; i++)
		{
			scanf("%s %s",str[0],str[1]);
			x = insert(str[0]);
			y = insert(str[1]);
			fx = find(x); 
			fy = find(y);
			if(fx != fy)
			{
				fa[fy] = fx;
				tot[fx] += tot[fy];
			}
			printf("%d\n",tot[fx]);
		}
	}
	return 0;
}





别人的:

#include<stdio.h>
#include<map>
#include<iostream>
using namespace std;
map<string,int> m;
int set[100005];
int num[100005];
int find(int x)
{
    int r=x;
    while(r!=set[r])
    r=set[r];
    int i=x;
    while(i!=r)
    {
        int j=set[i];
        set[i]=r;
        i=j;
    }
    return r;
}
void merge(int x,int y)
{
    int fx=find(x);
    int fy=find(y);
    if(fx!=fy)
    {
        set[fx]=fy;
        num[fy]+=num[fx];
        printf("%d\n",num[fy]);
    }
    else
    {
        printf("%d\n",num[fy]);
    }
}
int main()
{
    int t;
    char a[25];
    char b[25];
    while(scanf("%d",&t)!=EOF)
    {
        while(t--)
        {
            int n;
            scanf("%d",&n);
            for(int i=1;i<100005;i++)
            {
                set[i]=i;
                num[i]=1;
            }
            m.clear();
            int ans=1;
            for(int i=1;i<=n;i++)
            {
                scanf("%s%s",a,b);
                if(!m[a])
                {
                    m[a]=ans++;
                }
                if(!m[b])
                {
                    m[b]=ans++;
                }
                merge(m[a],m[b]);
            }
        }
    }
    return 0;
}




标签:hdu,set,hash,int,fy,include,num,maxn,3172
From: https://blog.51cto.com/u_16143128/6373661

相关文章

  • hdu 2795(线段树)
    解题思路:这道题很难想到是用线段树,确实转化的很巧妙实际上,我们只需要利用线段树(记录1-h)维护哪个位置的剩余空间最大即可,即1,2,......,h是线段树的叶子节点,我们每次要找的就是叶子节点的剩余空间的最大值,只要能够想到这里就很容易啦。。另外如果h>n的话,就令h=n,否则就是类似于位置多......
  • hdu 1698(线段树区间更新)
    解题思路:线段树区间更新水题。#include<iostream>#include<cstdio>#include<cstring>usingnamespacestd;constintmaxn=100005;structseg{ intl,r,sum,lazy;}tree[maxn<<2];voidbuild(intl,intr,intu){ tree[u].l=l; tree[u].r=r; t......
  • hdu 1511(dp)
    解题思路:两次dp确实很巧妙,我只想到了一次dp算出最后那个数最小,其实题目要求还要保证第一个数尽可能大,一开始也没有注意到。。AC:#include<stdio.h>#include<string.h>#include<algorithm>#include<iostream>#include<math.h>#include<stdlib.h>#include<time.h>usingnamesp......
  • hdu 5102(队列+节点扩展)
    TheK-thDistanceTimeLimit:8000/4000MS(Java/Others)    MemoryLimit:65536/65536K(Java/Others)ProblemDescriptionGivenatree,whichhasnnodeintotal.Definethedistancebetweentwonodeuandvisthenumberofedgeontheirunique......
  • hdu 5367(线段树+区间合并)
    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5367官方题解:对于求“高山脉”长度,可以利用线段树。树节点中保存左高度连续长度,左高度连续区间的高度,左高度连续区间的状态(即是否高于第一个高度不同的山),右高度连续长度,右高度连续区间的高度,右高度连续区间的状态,每段区间内的“......
  • hdu 5201(隔板法+容斥原理)
    TheMonkeyKingTimeLimit:8000/4000MS(Java/Others)    MemoryLimit:65536/65536K(Java/Others)ProblemDescriptionnpeaches.Andtherearemmonkeys(includingGoKu),theyarenumberedfrom1tom,GoKu’snumberis1.GoKuwa......
  • hdu 5086(dp)
    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5086题目大意:给出长度为n的数组,然后要求累计里面的每个子串的和。解题思路:这道题直接枚举肯定不行,所以要找递推关系。假设:{1,2,3,4}为某一个序列,假设我们已经找到了{1,2,3},接下来把{4}加入进去;由于{1,2,3}已经有{1},{2},{3},{1,......
  • hdu 5188(限制01背包)
    zhxandcontestTimeLimit:2000/1000MS(Java/Others)    MemoryLimit:65536/65536K(Java/Others)ProblemDescriptionAsoneofthemostpowerfulbrushesintheworld,zhxusuallytakespartinallkindsofcontests.Oneday,zhxtakespar......
  • hdu 5171(矩阵快速幂)
    GTY'sbirthdaygiftTimeLimit:2000/1000MS(Java/Others)    MemoryLimit:65536/65536K(Java/Others)ProblemDescriptiona,b∈S),andadda+b Input2≤n≤100000,1≤k≤1000000000).Thesecondlinecontainsnelementsai......
  • hdu 5157(manacher+前缀和+树状数组)
    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5157解题思路:我们可以先用mancher算法对字符串进行处理,把以每个点为中心的回文串半径求出来,然后进行处理。加入对以p为中心的点,从p-r[i]+1~p都是回文串的开头,那么对于每个回文串(开头是j)只要记录结尾从1~j-1的回文串个数,我们可......