Loading

<数据结构>XDOJ323.判断有向图中是否有环

问题与解答

问题描述
判断有向图中是否有环。
输入格式
输入数据第一行是一个正整数,表示n个有向图,其余数据分成n组,每组第一个为一个整数,表示图中的顶点个数n,顶点数不超过100,之后为有向图的邻接矩阵。
输出格式
输出结果为一行,如果有环,则输出1,如果无环,则输出0。按顺序输出这n个有向图的判断结果,前后结果的输出不加空格。
样例输入
3
2
0 1
0 0
4
0 1 0 0
0 0 0 1
0 0 0 1
1 0 0 0
3
0 1 1
0 0 0
0 0 0
样例输出
010

//判断有向图中是否有环
//本质:拓扑排序
#include<stdio.h>
#include<queue>
#include<algorithm>
using namespace std;
#define MaxN 100  //最大顶点数
int n;  //顶点数
int G[MaxN][MaxN];  //邻接矩阵保存图
int InDegree[MaxN] = {0};  //保存顶点入度
void TopoSort();     //拓扑排序判断有向环

int main(){
    int num, i, j, flag;
    scanf("%d", &num);
    while(num--){   //多点输入:执行num次
        scanf("%d", &n);
        fill(InDegree,InDegree+MaxN,0);  //每次都要重置InDegree数组!
        for(i = 0; i < n; i++){   //输入图的邻接矩阵
            for(j = 0; j < n; j++){
                scanf("%d", &flag);
                G[i][j] = flag;
                if(flag != 0)
                   InDegree[j]++;
            }
        }
        TopoSort();  //拓扑排序
    }
}

void TopoSort(){
    queue<int> q;
    int u,v;
    int node = 0;
    for(u = 0; u < n; u++){  //将入度为0的顶点入队
        if(InDegree[u] == 0){
            q.push(u);
        }
    }
    while(!q.empty()){  //若队列非空
        u = q.front();
        q.pop();  //u出队
        for(v = 0; v < n; v ++){  //扫描u的邻接点
            if(G[u][v] != 0){
                InDegree[v]--;  //邻接点入度-1
                if(InDegree[v] == 0)  //若入度变为0,入队
                    q.push(v);
            }
        }
        node++;  //已完成拓扑排序的顶点数目+1
    }
    if(node == n) printf("0");  //拓扑排序成功:无有向环
    else         printf("1");   //拓扑排序失败:存在有向环
}

题后反思

  1. 判断有向图中是否有环: 拓扑排序
    • 拓扑排序易错点:两层判断是嵌套关系,否则会进入死循环!!!
    if(G[u][v] != 0){
                InDegree[v]--;  //邻接点入度-1
                if(InDegree[v] == 0)  //若入度变为0,入队
                    q.push(v);
            }
    
  2. 写多点测试题时注意全局变量的初始化【fill(InDegree,InDegree+MaxN,0); //每次都要重置InDegree数组!】否则样例输出011
posted @ 2021-12-20 23:49  咪啪魔女  阅读(506)  评论(0编辑  收藏  举报