openjudge1308——Is It A Tree?

Posted robin20050901

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了openjudge1308——Is It A Tree?相关的知识,希望对你有一定的参考价值。

题目链接:http://bailian.openjudge.cn/practice/1308?lang=en_US

题目大意:给你一个集合,判断它是不是一颗树(无环,点的个数=边的个数+1,空树)并查集判断即可

解释都在代码里

 

#include<bits/stdc++.h>

#define rd(x) x=read()
#define N 1000005

using namespace std;
 
int Case=1;
int f[N];
int find(int x)
{
    if(x!=f[x])f[x]=find(f[x]);
    return f[x]; 
}//find函数 
map<int,int>vis;//记录节点是否出现过 
int cnt_v,cnt_e;//记录点与边的数量 

inline int read()
{
    int f=1,x=0;char s=getchar();
    while(s<0||s>9){if(s==-)f=-1;s=getchar();}
    while(s>=0&&s<=9){x=x*10+s-0;s=getchar();}
    return x*f;
}

void init()
{
    cnt_v=0,cnt_e=0;
    for(int i=0;i<N;i++)f[i]=i;
    vis.clear();
}//初始化 

bool check()
{
    if(cnt_v&&cnt_v!=cnt_e+1)return false;//如果不为空树且节点数不等于边数+1 
    return true;
}//判断是否满足 

void addEdge(int a,int b)
{
    if(!vis[a])cnt_v++;
    if(!vis[b])cnt_v++;
    cnt_e++,vis[a]=1,vis[b]=1;
}//加边 

void merge(int a,int b)
{
    int x=find(a),y=find(b);
    if(x!=y)f[x]=y;
}//合并 

int main()
{
    init();//初始化 
    int a,b;
    while(cin>>a>>b)
    {
        if(a==-1&&b==-1)return 0;//如果均为-1,结束 
        else if(a==0&&b==0)//如果一个case结束 
        {
            if(check())printf("Case %d is a tree.
",Case++);//满足 
            else printf("Case %d is not a tree.
",Case++);//不满足 
            init();        //再次初始化 
        }
        else if(a||b)addEdge(a,b);//如果有一个点不为0,加边 
        else merge(a,b);//否则归并 
    } 
    
    
    return 0;//一定要往下看 
}

 

读者可以试试,把这份代码提交,等待你的不是AC而是WA

为什么呢?

一路写下来没有什么问题呀?

有问题,有很大问题。

当我们符合最后一条(66行),要考虑一个问题,有没有可能既要归并,又要加边?

所以,要把65行的 else if 提前,提到最前!!!(没有正确AC代码提供,请读者自行修改上面那段代码)

 

以上是关于openjudge1308——Is It A Tree?的主要内容,如果未能解决你的问题,请参考以下文章

POJ1308 Is It A Tree?

POJ - 1308 Is It A Tree?并查集

POJ 1308 Is It A Tree? [并查集]

POJ 1308 Is It A Tree?

POJ 1308 Is It A Tree?--题解报告

POJ-1308 Is It A Tree?(并查集判断是否是树)