有向无环图:一个有向图不存在环,则称为有向无环图,简称DAG图。
AOV网:如果用DAG表示一个工程,其定点表示活动,用有向边< Vi,Vj>表示活动Vi必须先于活动Vj进行的这样一种关系,则将这种有向图称为定点表示活动的网络,记为AOV网。在AOV网中,活动Vi是活动Vj的前驱,活动Vj是Vi的直接后继,这种前驱和后继关系具有传递性,且任何活动Vi不能以它自己作为自己的前驱或后继。
拓扑排序:在图论中,有一个有向无环图的定点组成的序列,当且仅当满足下列条件时,称为该图的一个拓扑排序。
1)每个顶点只出现一次。
2)若顶点A在序列中排在顶点B的前面,则在图中不存在从顶点B到顶点A的路径。
对一个DAG图进行拓扑排序的算法有很多,比较常用的一种方法的步骤:
1)从DAG图中选择一个没有前驱的顶点并输出。
2)从图中删除该顶点和所有以它为起点的有向边。
3)重复1和2直到当前的DAG图为空或当前图中不存在无前驱的顶点为止。后一种情况则说明有向图中必然存在环。
leetcode207:
There are a total of n courses you have to take, labeled from 0 to n-1.
Some courses may have prerequisites, for example to take course 0 you have to first take course 1, which is expressed as a pair: [0,1]
Given the total number of courses and a list of prerequisite pairs, is it possible for you to finish all courses?
Example 1:
Input: 2, [[1,0]]
Output: true
Explanation: There are a total of 2 courses to take.
To take course 1 you should have finished course 0. So it is possible.
Example 2:
Input: 2, [[1,0],[0,1]]
Output: false
Explanation: There are a total of 2 courses to take.
To take course 1 you should have finished course 0, and to take course 0 you should
also have finished course 1. So it is impossible.
解题思路:
判断输入是否为拓扑排序,若是拓扑排序,返回true;否则返回false。
代码实现(以leetcode207为例):
class Solution {
public:
bool canFinish(int numCourses, vector<pair<int, int>>& prerequisites) {
int Hash[10010];//每个节点的入度
vector<vector<int>> v(numCourses);//用于存储每个节点相邻的边
stack<int> s;//存放入度为0的节点
memset(Hash, 0, sizeof(Hash));
for(int i =0 ; i < prerequisites.size();i++){
pair<int, int>p = prerequisites[i];
int x = p.first;
int y = p.second;
cout<<"x = "<<x <<"y = "<<y<<endl;
v[x].push_back(y);
++Hash[y];
}
for(int i = 0; i < numCourses; i++){
if(Hash[i] == 0){
s.push(i);
}
}
while (!s.empty()) {
int cur = s.top();//找到入度为0的点
s.pop();
for(int i = 0; i < prerequisites.size(); i++){
pair<int, int>p = prerequisites[i];
int x = p.first;
int y = p.second;
if(cur == x){
for(int j = 0; j < v[cur].size(); j++){
--Hash[v[cur][j]];//删除以该点为起点的所有有向边
if(Hash[v[cur][j]] == 0)
s.push(v[cur][j]);
}
break;
}
}
}
for(int i = 0; i < numCourses; i++){
if(Hash[i] != 0)
return false;
}
return true;
}
};