您的位置:首页 > 其它

【Sicily】1004. 无环图

2017-06-28 00:26 260 查看

题目描述

在图论中,如果一个有向图从任意顶点出发无法经过若干条边回到该点,则这个图是一个有向无环图(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 University
class 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;
}
};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息