• hdu Is It A Tree?


      判定给定的边序列是否过程一棵树。我用到的判定方法是:第一步:判定  边数是否等于顶点数-1  第二:判定是否只有一个根节点  。当然还要考虑是否为空树的情况。

      但是代码交上去,好几遍都是Runtime Error。。。看了一下discuss,并没有觉得自己的程序有错误。但是别人类似的代码却能过掉。。。说明自己的代码写的还是有很大的不足啊。。。

    先附上自己的代码,是在不知道有什么错误。看discuss,好像有的代码数组只开到20就a掉了。

    #include"iostream"
    #include"stdio.h"
    #include"algorithm"
    #include"string"
    #include"string.h"
    #include"cmath"
    #include"queue"
    #include"stack"
    #include"vector"
    #include"ctype.h"
    using namespace std;
    const int mx=100005;
    int fa[mx];
    bool visited[mx];
    bool flag1,flag2;
    int src,dest,edgenum,vernum,icase=1;
    
    void Set()
    {
        for(int i=0;i<mx;i++)
            fa[i]=i;
    }
    
    int Find(int x)
    {
        while(x!=fa[x]) x=fa[x];
        return fa[x];
    }
    
    void Union()
    {
        int fsrc=Find(src);
        int fdest=Find(dest);
        fa[fdest]=fsrc;
    }
    void Init()
    {
       Set();
       memset(visited,false,sizeof(visited));
       edgenum=0;
       vernum=0;
       flag1=flag2=false;
    }
    bool judge()//判断是否只有一个根节点
    {
        int i,j;
        for(i=0;i<mx;i++)
            if(visited[i]) break;
        int temp=Find(i);
        for(j=i;j<mx;j++)
            if(visited[j]&&Find(j)!=temp) return true;
        return false;
    }
    
    int main()
    {
      //  freopen("E:\in.txt","r",stdin);
        Init();Set();
        while(scanf("%d%d",&src,&dest))
        {
            if(src==-1||dest==-1) break;
            if(src==0&&dest==0)
            {
                if(edgenum==0){printf("Case %d is a tree.
    ",icase++);Init();continue;}
                if(edgenum!=vernum-1) flag1=true;
                if(judge()) flag2=true;
                if(flag1||flag2)
                    printf("Case %d is not a tree.
    ",icase++);
                else
                    printf("Case %d is a tree.
    ",icase++);
                Init();Set();
                continue;
            }
            edgenum++;
            if(!visited[src]) {visited[src]=true;vernum++;}
            if(!visited[dest]) {visited[dest]=true;vernum++;}
            Union();
        }
        return 0;
    }
    View Code

    下面是我参考别人的代码写的,思路和我基本一样,然而,却还是runtime error。。。有点不爽。

    #include"iostream"
    #include"stdio.h"
    #include"cmath"
    #define mx 100005
    using namespace std;
    struct node
    {
        bool num;//判断这个数字是否用过
        int root;//记录其父亲节点
        int indegree;//用来记录该节点的入度
    };
    node tnode[mx];//定义这棵树的结点数组
    int src,dest;//边的起点和终点
    int root_num;//根节点的数目
    int icase=1;//案例个数
    bool is_tree;//判断是否为一棵树
    
    int Find(int x)//查找根节点
    {
        if(tnode[x].root!=x)
            return tnode[x].root = Find(tnode[x].root);
        return tnode[x].root;
    }
    
    void Union()//将两个结合合并起来
    {
        int fsrc=Find(src);
        int fdest=Find(dest);
        if(fsrc!=fdest)
            tnode[fdest].root=fsrc;
        else  if(src!=dest)
            is_tree=false;
    }
    
    void Init()//初始化函数
    {
        int i;
        is_tree=true;
        root_num=0;
        for(i=0;i<mx;i++)
        {
            tnode[i].num=false;
            tnode[i].root=i;
            tnode[i].indegree=0;
        }
    }
    
    void Output()//输出函数
    {
        int i;
        for(i=1;i<mx;i++)
        {
            if(tnode[i].num&&tnode[i].indegree>1)
                {is_tree=false;break;}
            if(tnode[i].num&&tnode[i].root==i)
                root_num++;
        }
        if(root_num>1) is_tree=false;
        if(is_tree)
             printf("Case %d is a tree.
    ",icase++);
        else
             printf("Case %d is not a tree.
    ",icase++);
    }
    
    void Input()//输入函数
    {
        while(scanf("%d%d",&src,&dest))
        {
            if(!is_tree&src!=0&&dest!=0) continue;
            if(src==-1||dest==-1) return;
            if(src==0&&dest==0)
            {
                Output();
                Init();
                continue;
            }
            if(src==dest) is_tree=false;
            tnode[src].num=true;
            tnode[dest].num=true;
            tnode[dest].indegree++;
            Union();
        }
    }
    
    int main()
    {
     //   freopen("E:\in.txt","r",stdin);
        Init();
        Input();
        return 0;
    }
    View Code

    Runtime Error(ARRAY_BOUNDS_EXCEEDED) // array bounds exceed     数组越界
    Runtime Error(DIVIDE_BY_ZERO) //divisor is nil                                   除零
    Runtime Error(ACCESS_VIOLATION) //illegal memory access     非法内存读取//是我出现的错误,然而我既没有用到指针,数组也没有越界。。。
    Runtime Error(STACK_OVERFLOW) //stack overflow                             系统栈过载

    这是discuss里的一个程序,感觉和我写的差不多,居然过掉了。。。我也是醉了。

    #include <stdio.h>
    
    const int max_num = 100000+10;
    typedef struct
    {
        int num,root,conn;//数据、根、入度
    }Node;
    
    Node node[max_num];
    
    void init()
    {
        for(int i = 0; i < max_num; i++)
        {
            node[i].conn = 0;//入度初始化为0
            node[i].root= i;//根记录为自身
            node[i].num=0;//标记数字是否被使用过,0:没有被使用过,1:使用过了
        }
    }
    
    int find_root(int a)
    {
        if(node[a].root!=a)
            return node[a].root = find_root(node[a].root);
        return node[a].root;
    }
    
    void union_set(int a,int b)
    {
        a = find_root(a);
        b = find_root(b);
        if(a==b)//同一个根,说明是在同一个树下
        return;
        node[b].root=a;//把b的根赋为a的根,此时a已经是根,num==root
    }
    
    int main()
    {
        int n,m;
        int i = 1;
        bool flag=true;//true:是个树,false:不是树
        init();
        while(scanf("%d%d",&n,&m)!=EOF&&n>=0&&m>=0)
        {
            if(!flag&&n!=0&&n!=0)continue;//已经确定不是树了,就继续循环
            if(n==0&&m==0)
            {
                int root_num=0;
                for(int j = 1; j < max_num;j++)
                {
                    //判断是否为森林,如果,root_num用来记录根的数目
                    if(node[j].num && find_root(j)==j)
                    root_num++;
                    if(node[j].conn>1)//如果出现某个节点的入度超过1,不是树
                    {
                        flag = false;
                        break;
                    }
                }
                if(root_num>1)//连通分支大于1,是森林不是树
                    flag=false;
                if(flag)
                printf("Case %d is a tree.
    ",i++);
                else printf("Case %d is not a tree.
    ",i++);
                flag = true;
                init();
                continue;
            }
            if(m!=n&&find_root(n)==find_root(m))
            flag = false;
            else
            {
                //将m,n,记录为节点
                node[m].num = 1;
                node[n].num = 1;
                node[m].conn++;//入度增加一
                union_set(n,m);
            }
        }
        return 0;
    }
    View Code
  • 相关阅读:
    C语言实现数据机构链表的基本操作(从键盘输入生成链表、读取数组生成链表)
    MySql-8.0.x免安装版下载与配置,Navicat打开数据库链接报错1251的解决办法
    win10彻底卸载和删除MySql
    Linux/(centos、unix等)的ssh双向免密登录原理和实现
    笔趣阁小说-圣墟-爬虫源代码
    C语言实现顺序表的基本操作(从键盘输入 生成线性表,读txt文件生成线性表和数组生成线性表----三种写法)
    python语言开发环境配置
    Python闭包详解
    结对作业
    Java第九次作业——接口回调
  • 原文地址:https://www.cnblogs.com/acm-jing/p/4657314.html
Copyright © 2020-2023  润新知