算法分析与设计课程作业第五周#1
这周选择一道图论的medium题目来做,题目是一个经典的排课问题,主要是考察判断一个有向图有无环的。
以下是题目:
207. Course Schedule
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?
For example:
2, [[1,0]]
There are a total of 2 courses to take. To take course 1 you should have finished course 0. So it is possible.
2, [[1,0],[0,1]]
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.
Note:
1.The input prerequisites is a graph represented by a list of edges, not adjacency matrices. Read more about how a graph is represented.
2.You may assume that there are no duplicate edges in the input prerequisites.
思路
算法课上已经讲过怎么判断一个图有无环了,就是深度优先搜索遍历图,根据得到的各个点pre值与post值是否满足某条边(u,v)上两点pre[v]<=pre[u]<post[u]<=post[v],若满足,则图存在前向边(回边),即图中存在环。明白这些后,解决问题就没难度了。在这之前我实现图都是使用邻接矩阵,这次就尝试下使用邻接表。
顺便还学习了下pair的用法:
1.构造:
pair<int, double> p0(1, 2.4);
2.访问两个元素(通过first和second):
pair<int, double> p1; //使用默认构造函数
p1.first = 3;
p1.second = 3.6;
3.利用make_pair和赋值operator = 赋值:
pair<int, double> p2;
p2 = make_pair(1, 1.8);
大致就这么多。
代码
这次没有出什么错误,打完就过了,就直接上正确代码了。
class Solution {
public:
void traverse(vector<int> edge[], int vertice, int pre[], int post[], int &time, bool found[]){
++time;
pre[vertice] = time;
found[vertice] = true;
vector<int> ::iterator iter;
for(iter = edge[vertice].begin(); iter != edge[vertice].end(); iter++){
if(!found[*iter]){
traverse(edge, *iter, pre, post, time, found);
}
}
++time;
post[vertice] = time;
}
bool canFinish(int numCourses, vector<pair<int, int>>& prerequisites) {
vector<int> edge[numCourses];
int pre[numCourses];
int post[numCourses];
int time = 0;
bool found[numCourses];
for(int j = 0; j < numCourses; j++){
found[j] = false;
}
vector<pair<int, int>> ::iterator i = prerequisites.begin();
for( ; i != prerequisites.end(); i++){
edge[i->second].push_back(i->first);
}
for(int j = 0; j < numCourses; j++){
if(!found[j]){
traverse(edge, j, pre, post, time, found);
}
}
for(int j = 0; j < numCourses; j++){
vector<int> ::iterator iter;
for(iter = edge[j].begin(); iter != edge[j].end(); iter++){
if(pre[*iter] <= pre[j] && post[j] <= post[*iter]) return false;
}
}
return true;
}
};