HihoCoder 1322 Tree or Not

本文是作者在算法分析与设计课程中的一次作业记录,涉及如何判断一个无向图是否为树。作者通过深度优先搜索判断连通性和边的数量与节点数量的关系来确定图是否为树,并分享了代码实现过程。
摘要由CSDN通过智能技术生成

 啰啰嗦嗦写在前面的话:   

这学期有算法分析与设计课,每周的作业是在Vjudge上刷相应的题目,为了方便以后回顾我就把代码搬到这里来了 。也希望能帮助其他刷题的朋友,代码不要完完全全复制粘贴(强调强调),重要的是看思路,不懂的大家可以一起交流!米娜桑,一起加油哇!

翠花儿,上题!

Given an undirected graph G which has N vertice and M edges, determine whether G is a tree.

Input

The first line contains an integer T, the number of test cases. (1 ≤ T ≤ 10) For each test case the first line contains 2 integers N and M. (2 ≤ N ≤ 500, 1 ≤ M ≤ 100000)

The following M lines each contain 2 integers a and b representing that there is an edge between a and b. (1 ≤ a, b ≤ N)

Output

For each test case output "YES" or "NO" indicating whether G is a tree or not.

Sample Input

2
3 2
3 1
3 2
5 5
3 1
3 2
4 5
1 2
4 1 

Sample Output

YES
NO

思路:

首先,自由树是一个连通且无环的无向图。在判断连通性时我是用深度优先搜索进行判断的,无环我使用了|E| =|V|-1 来判断的。

在构建图的时候我自己写了一个链表,后来觉得这样做很傻 - - 明明有vector可以用,何乐而不为呢? 

代码如下:

#include <iostream>
//自由树是一个连通/无环的无向图
#include <queue>
#define MAX  501
using namespace std;
struct ArcNode //边表节点
{
    int adjvex;
    ArcNode* next;
};
struct VertexNode //顶点表节点
{
    int vertex;
    ArcNode* firstedge;
};
class AdjGraph //邻接链表表示图
{
private:
    VertexNode adjlist[MAX];//存放顶点的数组
    int vertexNum, arcNum;//图的顶点数和边数
    int visited[MAX]; //用来判断顶点是否被访问过

public:
    AdjGraph(int n, int m);//构造函数 n个顶点 m条边
    void Insert (int a, int b);
    void DFS(int v); //深度优先搜索
    bool validTree();
    void show();//显示邻接链表构造 测试用
};
AdjGraph::AdjGraph(int n, int m)
{
    vertexNum = n;
    arcNum = m;
    for(int i = 0; i < vertexNum ;i++)
    {
        visited[i] = 0;
        adjlist[i].vertex = i+1;//顶点是从1开始的
        adjlist[i].firstedge = NULL;
    }
}
void AdjGraph::Insert(int a, int b)
{
    ArcNode *pArc = new ArcNode();
    pArc->adjvex = b;
    if(adjlist[a-1].firstedge == NULL)
    {
        adjlist[a-1].firstedge = pArc;
    }
    else
    {
        ArcNode *p = adjlist[a-1].firstedge;
        while(p->next!=NULL)
        {
            p = p->next;
        }
        p->next = pArc;
    } //接下来重复对 b->a

    ArcNode *fpArc = new ArcNode();
    fpArc->adjvex = a;
    if(adjlist[b-1].firstedge == NULL)
    {
        adjlist[b-1].firstedge = fpArc;
    }
    else
    {
        ArcNode *p = adjlist[b-1].firstedge;
        while(p->next!=NULL)
        {
            p = p->next;
        }
        p->next = fpArc;
    }
}
void AdjGraph:: DFS(int v)
{
    visited[v-1] = 1;
    ArcNode *p = adjlist[v-1].firstedge;
    while(p!=NULL)
    {
        int j = p->adjvex;
        if(visited[j-1]==0)
            DFS(j);
        p = p->next;
    }
}
void AdjGraph:: show()
{
    cout<<"邻接链表: "<<endl;
    for(int i =0; i < vertexNum ; i++)
    {
        cout << adjlist[i].vertex;
        ArcNode *p = adjlist[i].firstedge;
        while (p != NULL)
        {
            cout<< "-> "<<p->adjvex;
            p = p->next;
        }
        cout<< " ->NULL"<<endl;
    }
}
bool AdjGraph::validTree()
{
    //证明图无环用|E|=|V|-1
    if (arcNum !=(vertexNum -1))
        return false;
    //证明图是连通的
    DFS(1);
    for(int i =0; i < vertexNum; i++)
    {
        if (visited[i]==0)
            return false;
    }
    return true;
}



int main()
{
    int T=0;
    cin>>T;
    for (int i = 0; i < T; i++)
    {
        int N=0;
        int M=0;
        cin>>N>>M;
        AdjGraph myGraph(N,M);
        for(int j = 0; j < M ;j++)
        {
            int a,b;
            cin>>a>>b;
            myGraph.Insert(a,b);
        }
        //myGraph.show();
        if(myGraph.validTree()) cout<<"YES"<<endl;
        else cout<<"NO"<<endl;
    }
    /*AdjGraph myGraph(3,2);
    myGraph.Insert(3,1);
    myGraph.Insert(3,2);
    myGraph.show();
    */
    return 0;
}

 

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值