【Sicily】1004. 无环图

来源:互联网 发布:斯凯网络 编辑:程序博客网 时间:2024/04/24 13:00

题目描述

在图论中,如果一个有向图从任意顶点出发无法经过若干条边回到该点,则这个图是一个有向无环图(Directed Acyclic Graph,DAG). 对于一个n个节点的有向图(节点编号从0到n-1),请判断其是否为有向无环图.

图的节点数和边数均不多于100000.

请为下面的Solution类实现解决上述问题的isDAG函数,函数参数中n为图的节点数,edges是边集,edges[i]表示第i条边从edges[i].first指向edge[i].second. 如果是有向无环图返回true,否则返回false.

class Solution {public:       bool isDAG(int n, vector<pair<int, int>>& edges) {    }};

例1:
n = 3,edges = {(0, 1), (0, 2)},函数应返回true.

例2:
n = 2,edges = {(0, 1), (1, 0)},函数应返回false.

注意:你只需要提交Solution类的代码,你在本地可以编写main函数测试程序,但不需要提交main函数的代码. 注意不要修改类和函数的名称.

解题思路

深搜+剪枝。
按照深度优先顺序遍历,如果在遍历的过程中发现有回边,也就是发现有从子节点指向父节点的边,那么说明该有向图是有环的。
为了后续操作的方便,可以将输入中的边集,先转换为邻接表。
另外,如果某一个节点包含在一个环中,那么只需要一次深搜就可以发现,所以可以通过标记访问状态来进行剪枝。

AC代码

// Problem#: 20620// Submission#: 5148745// The source code is licensed under Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License// URI: http://creativecommons.org/licenses/by-nc-sa/3.0/// All Copyright reserved by Informatic Lab of Sun Yat-sen Universityclass Solution {public:    bool dfs(int root, vector<bool>& isVisited, vector<bool>& curBack,                 map<int, vector<int> >& adjTable) {        isVisited[root] = true;        curBack[root] = true;        for (int i = 0; i < adjTable[root].size(); ++i) {            int nextNode = adjTable[root][i];            if (curBack[nextNode])                return false;            if (!adjTable[nextNode].empty() && !isVisited[nextNode])                 if(!dfs(nextNode, isVisited, curBack, adjTable))                     return false;            }        curBack[root] = false;        return true;    }    bool isDAG(int n, vector<pair<int, int> >& edges) {        map<int, vector<int> > adjTable;        for (int i = 0; i < edges.size(); ++i) {            if (edges[i].first == edges[i].second)                return false;            adjTable[edges[i].first].push_back(edges[i].second);        }        vector<bool> isVisited;        vector<bool> curBack;        for (int i = 0; i < n; ++i) {            isVisited.push_back(false);            curBack.push_back(false);        }        for (int i = 0; i < n; ++i) {            if (!adjTable[i].empty() && !isVisited[i]) {                if(!dfs(i, isVisited, curBack, adjTable))                    return false;            }        }        return true;    }};                                 
原创粉丝点击