简单并查集的使用。1、判断是否存在回路。2、判断图是否连通。---------开始时我只考虑了是否有环,而没有考虑是否连通。

CODE:

 

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
using namespace std;

const int maxn = 100010;

int p[maxn], rank[maxn];
int flag, sign[maxn];            //判断是否是连通图 

int find(int x)
{
    return p[x] == x? x: p[x] = find(p[x]);
}

void Union(int x, int y)
{
    int i = find(x);
    int j = find(y);
    if(i == j)
    {
        flag = 0;
        return ;
    }
    if(rank[i] > rank[j])
    {
        p[j] = i;
    }
    else
    {
        if(rank[i] == rank[j])
        {
            rank[j]++;
        }
        p[i] = j;
    }
}

void init()
{
    for(int i = 0 ; i < maxn ;i++) p[i] = i;
    memset(rank, 0sizeof(rank));
    memset(sign, 0sizeof(sign));
}

int main()
{
    int x, y;
    while(scanf("%d%d", &x, &y))
    {
        int i, j;
        flag = 1;
        if(x == -1 && y == -1break;
        if(x == 0 && y == 0)
        {
            printf("Yes\n");
            continue;
        }
        init();            //预处理 
        sign[x] = sign[y] = 1;
        Union(x, y);
        while(scanf("%d%d", &x, &y))
        {
            if(x == 0 && y == 0break;
            Union(x, y);
            sign[x] = sign[y] = 1;
        }            //判断是否有环 
        int cnt = 0;
        for(i = 0 ; i < maxn; i++)
        {
            if(sign[i] && p[i] == i)    cnt++;
             if(cnt > 1) flag = 0;
        }            //判断是否连通 
        if(flag)
        {
            printf("Yes\n");
        }
        else
        {
            printf("No\n");
        }
    }
    return 0;
}

 

posted on 2012-08-05 17:25  有间博客  阅读(163)  评论(0编辑  收藏  举报