欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

warshall 判断某无向图是否是一个树

程序员文章站 2022-07-09 19:38:49
判断一个图是否构成树 问题 给定一个无向图,判断该图是否构成树。 输入 输入有若干测试样例。第一行是测试样例个数,接下来若干测试样例。 每个测试样例的第一行是结点数n,而且结点用1,2,…, n编号。 第二行是边数m,接下来是 m个结点对。 输出 如果一个图是树,则打印“YES",否则打印"NO"。 ......

判断一个图是否构成树

问题

给定一个无向图,判断该图是否构成树。

输入

输入有若干测试样例。第一行是测试样例个数,接下来若干测试样例。 每个测试样例的第一行是结点数n,而且结点用1,2,…, n编号。 第二行是边数m,接下来是 m个结点对。

输出

如果一个图是树,则打印“yes",否则打印"no"。每个输出占一行。

输入样例

3

3
2
1 2
2 3

3
3
1 2
2 3
1 3

3
1
2 3

输出样例

yes
no
no

思路:

树是没有简单回路的连通无向图

判断方式:

  1. 无向图是连通的(用warshall算法判断)
  2. 没有简单回路(根据树的性质:带有n个结点的树含有n-1条边)

代码实现

#include <stdio.h>
//warshall 算法 //传递闭包
void warshall(int matrix[][100],int size){
    for(int j = 0; j < size; j ++){
        for(int i = 0; i < size; i ++){
            if(matrix[i][j] == 1){
                for(int k = 0; k < size; k ++){
                    matrix[i][k] = matrix[j][k] || matrix[i][k];
                }
            }
        }
    }
}

int main(){
    int num;
    scanf("%d",&num);//循环次数
    
    for(int m = 0;m < num; m++){
        int flag = 1;
        int mat[100][100] = {0};
        int v,e;
        scanf("%d",&v);//点数
        scanf("%d",&e);//边数
        //输入所有边
        for(int i = 0; i < e; i++){
            int j,k;
            scanf("%d",&j);
            scanf("%d",&k);
            mat[j-1][k-1] = 1;
            mat[k-1][j-1] = 1;
            mat[i-1][i-1] = 1;
        }
        //1 判断是否有回路(树的性质)
        if(v-e!=1){
           flag = 0;
        }

		//2 判断是否连通(warshall 传递闭包)
        warshall(mat, v);
        for(int j = 0; j < v; j++){
            for(int k = 0; k < v; k++){
                if(mat[j][k]!=1){
            flag = 0;
        }
            }
        }
        if(flag==0){
            printf("no\n");
        }else{
              printf("yes\n");
        }
        
    }
}