并查集 Hdu 1272

HDU 1272

也就是:给出多组数据
给出0,0,开始处理之前所给的,不能成环,只能有一个根节点
给出-1 -1 结束

不能成环:在join函数里面添加一个判断,标记flag
只能有一个根节点:循环判断给出的数,根节点数量,cnt只能为1

注意1:给出的数据不是连续的数,所以要有vis数组标记给出的数
注意2:只给0,0应是Yes

#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<queue>
#include<vector>
#include<string>
#define INF 0x3f3f3f3f
using namespace std;
const int maxn = 100005;
typedef long long ll;
int pre[maxn];
bool vis[maxn];
bool flag = 0;
int find(int x){
    int r = x;
    while(r!=pre[r])
        r = pre[r];
    while(x!=r){
        int t = pre[x];
        pre[x] = r;
        x = t;
    }
    return r;
}
void join(int x,int y){
    int fx = find(x);
    int fy = find(y);
    if(fx!=fy)
        pre[fx]  = fy;
    else{
        flag = 1;
    }
}
int main(){
    int x,y;
    while(~scanf("%d %d",&x,&y)){   //读入第一个
        if(x==-1 && y==-1)      //跳出
            break;
        if(x==0 && y==0){
            printf("Yes\n");
            continue;
        }
        memset(vis,0,sizeof(vis));
        for(int i=0; i<maxn; i++)
            pre[i] = i;

        int mmax = max(x,y);
        join(x,y);
        flag = 0;
        vis[x] = vis[y] = 1;
        
        while(scanf("%d %d",&x,&y) && x && y){      //读入剩下数据直到0 0
            mmax = max(mmax,max(x,y));
            join(x,y);
            vis[x] = vis[y] = 1;
        }
        //不能成环
        if(flag){
            printf("No\n");
            continue;
        }
        //只能有一个父节点
        int cnt = 0;
        for(int i=1; i<=mmax; i++)
            if(vis[i] && pre[i] == i)
                cnt++;
        if(cnt==1)
            printf("Yes\n");
        else
            printf("No\n");

    }
    return 0;
}

发布了62 篇原创文章 · 获赞 0 · 访问量 1738

猜你喜欢

转载自blog.csdn.net/jhckii/article/details/104565179