并查集 浙师大oj1212

亲戚——高级

Time Limit: 1000MS Memory Limit: 65536K
Total Submissions: 299 Accepted: 129

Description

若某个家族人员过于庞大,要判断两个是否是亲戚,确实还很不容易,现在给出某个亲戚关系图,求任意给出的某个人所在家族的人数。
规定:x和y是亲戚,y和z是亲戚,那么x和z也是亲戚。如果x,y是亲戚,那么x的亲戚都是y的亲戚,y的亲戚也都是x的亲戚。

Input

第一行:三个整数n,(n<=100,000,m<=200,000),分别表示有n个人,m个信息。
以下m行:信息包含两种形式:
M a b:表示a和b具有亲戚关系。
Q a:要求输出a所在家族的人数。

Sample Input

5 10 M 3 2 Q 4 M 1 2 Q 4 M 3 2 Q 1 M 3 1 Q 5 M 4 2 Q 4

Sample Output

1 1 3 1 4

#include <stdio.h>
#include <string.h>
struct A
{
  int s;
  int sl;
};
struct A a[100001];
int main()
{
    int n,m,y,z,x,k;
    char r;
    for(int i=1;i<=100001;i++)
    {
      a[i].s=i;a[i].sl=1;
    }
    while(scanf("%d%d",&n,&m)!=EOF)
    {
      getchar();
      for(int i=1;i<=m;i++)
      {
        scanf("%c",&r);
        getchar();
        if(r=='M')
        {
          scanf("%d%d",&z,&y);getchar();
          while(a[z].s!=z){z=a[z].s;}\\寻找初始地址也就是亲戚数所存的位置
          while(a[y].s!=y){y=a[y].s;}          
          if(a[z].s!=a[y].s)
          {
          if(a[a[z].s].sl>a[a[y].s].sl){x=a[z].s;k=a[y].s;}
          else{x=a[y].s;k=a[z].s;}
          a[a[y].s].s=x;
          a[a[z].s].s=x;
          if(x!=k){a[x].sl+=a[k].sl;}
          else{a[x].sl++;}
          }
        }
        if(r=='Q'){scanf("%d",&x);getchar();while(a[x].s!=x){x=a[x].s;}printf("%d\n",a[a[x].s].sl);}
      }
    }
  return 0;                                                   
}

让所有亲戚的值放在1个地址上,然后所有该人的亲戚的亲戚数位置指向该人地址

上一篇:C#MUD英雄大作战二、乔峰篇(副源码文件连接)


下一篇:ps 查看进程之间的关系Ssl, Sl等