码迷,mamicode.com
首页 > 其他好文 > 详细

openjudge1308——Is It A Tree?

时间:2018-12-20 21:06:11      阅读:186      评论:0      收藏:0      [点我收藏+]

标签:false   初始   etc   判断   clear   http   getc   链接   c代码   

题目链接: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.\n",Case++);//满足 
            else printf("Case %d is not a tree.\n",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?

标签:false   初始   etc   判断   clear   http   getc   链接   c代码   

原文地址:https://www.cnblogs.com/Robin20050901/p/10152222.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!