并查集——检查图中是否有环

  • 题目链接:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=1645

  • 题意:

    • 每次输入一对数字,(两个数字不相等,不输入重复对),当有若干个数字对中含有的数字种类和总的数字的对数相等时候,爆炸,这时拒绝输入这一对数字,当输入单个-1时输出拒绝的次数
  • 分析:

    • 将每一对数字连线,构成一个图,我们即可发现爆炸的情况即点数=边数 情况,即图中有环的情况,所以使用并查集判断图中有无环
  • AC代码:


/*************************************************************************
    > File Name: D.cpp
    > Author: Akira
    > Mail: [email protected]
    > Created Time: 2017年01月13日 星期五 20时59分05秒
 ************************************************************************/

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
typedef long long LL;
typedef unsigned long long ULL;
typedef long double LD;
#define MST(a,b) memset(a,b,sizeof(a))
#define CLR(a) MST(a,0)
#define Sqr(a) ((a)*(a))

using namespace std;

#define MaxN 100005
#define MaxM MaxN*10
#define INF 0x3f3f3f3f
#define bug cout << 88888888 << endl;
#define MIN(x,y) (x
#define MAX(x,y) (x>y?x:y)
int ans,a,b;
int pre[MaxN];
int find(int x)                         
{ 
    int r=x;
    while(pre[r]!=r)                                                        
          r=pre[r];
    int i=x, j;
    while(i!=r)                                                                     
    {
         j=pre[i]; 
         pre[i]=r; 
         i=j;
    }
    return r;
}
void join(int x,int y)                              
{
    int fx=find(x),fy=find(y);
    if(fx!=fy)
        pre[fx]=fy;
    else ans++;
}

int main()
{
    while(~scanf("%d", &a))
    {
        while(a!=-1)
        {
            scanf("%d", &b);
            if(pre[a] == 0) pre[a] = a;
            if(pre[b] == 0) pre[b] = b;
            join(a,b);
            scanf("%d", &a);
        }
        cout << ans << endl;
        ans = 0;
        CLR(pre);
    }
}

你可能感兴趣的:(数据结构)