简单不相交集-1(基本应用-亲戚关系)

/*
 *Copyright (c) 2007, cn.edu.seu.cose
 *File: main.c
 *Description: Main Function
 *             1.输入两个整数(人数,关系对数)
 *             2.输入要检查的关系对数及关系对
 *
 *Author: knightzzy
 *Date: 2007.5.5
 */
#include <stdio.h>
#include "disjoint.h"

int main (void)
{
 int i, a, b, c, d, s, n, m;
 
 printf("请输入两个整数,若想退出请输入:0 0/n");
 InitSet ();
 while ((scanf("%d%d", &n, &m)==2) && (m || n))
 {
  for (i=0; i<n; i++)
  {
   MakeSet (i);
  }
  for (i=0; i<m; i++)
  {
   scanf("%d %d", &a, &b);
   Union (a, b);
  }
  printf("输入想要检查的关系对的数量:/n");
  scanf ("%d", &s);
  printf("输入想要检查的关系对:/n");
  for (i=0; i<s; i++)
  {
   scanf("%d %d", &c, &d);
   if (FindSet(c) == FindSet(d))
   {
    printf("YES/n");
   }
   else
   {
    printf("NO/n");
   }
  }
  printf("请输入两个整数,若想退出请输入:0 0/n");
 }
 return 0;
}

 

/*
 *Copyright (c) 2007, cn.edu.seu.cose
 *File: disjoint.h
 *
 *Version: 1th
 *Author: knightzzy
 *Date: 2007.5.4
 */
#ifndef _DISJOINT_H
#define _DISJOINT_H

#define MAXN 100

int set[MAXN], rank[MAXN];

void InitSet (void);               //初始化数据结构
int FindSet (int i);               //
void MakeSet (int i);              //生成一个新的集合,只含i
void Link (int i, int j);          //
void Union (int i, int j);

#endif

 

/*
 *Copyright (c) 2007, cn.edu.seu.cose
 *File: disjoint.c
 *
 *Version: 1th
 *Author: knightzzy
 *Date: 2007.5.4
 */
#include <string.h>
#include "disjoint.h"

//初始化数据结构
void InitSet (void)
{
 memset (set, 0, sizeof(set));
}
//寻找元素i,返回其代表(根)
int FindSet (int i)
{
 if (set[i] != i)
 {
  set[i] = FindSet (set[i]);
 }
 return set[i];
}
//生成一个新的集合,只含i
void MakeSet (int i)
{
 set[i] = i;
 rank[i] = 0;
}
//将根为a,b的树合并起来,以秩大的作为新树的根
void Link (int a, int b)
{
 if (rank[a] > rank[b])
 {
  set[b] = a;
 }
 else
 {
  set[a] = b;
  if (rank[a] == rank[b])
  {
   rank[b]++;
  }
 }
}
//将含元素i,j的集合合并
void Union (int i, int j)
{
 Link (FindSet(i), FindSet(j));

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值