《演算法設計與分析》第三週作業
阿新 • • 發佈:2018-11-26
《演算法設計與分析》第三週作業
標籤(空格分隔): 課堂作業
文章目錄
姓名:李**
學號:16340114
題目:Course Schedule(https://leetcode.com/problems/course-schedule/description/)
注:本篇部落格中所有圖片均來自教科書Algorithms(Dasgupta)
題目概要
把題目翻譯一下就是要判斷一個有向圖有沒有環,也就是判斷一個圖是不是dag。
一開始的時候以為特簡單,還說這怎麼就是medium難度,不就是做一個深度搜索嘛
後來仔細想了想,深搜好像是判斷連通與否的,不是判斷有沒有環的TAT
思路
思路一
將輸入的有向圖做一次拓撲排序,如果可以成功進行拓撲排序,即該有向圖無環,如果不能進行拓撲排序,即該有向圖有環。
思路二
第二種思想是應用教科書(Algorithms(Dasgupta))裡的思想,把輸入的有向圖轉換成DFS樹,判斷有無回邊(backedge)即可判斷該圖是不是dag。
Property
具體實現
首先將輸入的邊連結串列(edge list)轉換成鄰接表(Adjacency lists)。按照書本的方法,進行一次深度搜索,對節點進行preVisit與postVisit時打上clock標記(具體請看教材第三章)。深度搜索完成後,按照下圖,檢測圖有沒有回邊,輸出結果,完成。
心得
現學現用真爽。
原始碼:
class Solution
{
public:
Solution ()
{
clock = 1;
}
bool canFinish(int numCourses, vector<pair<int, int>>& prerequisites)
{
//handle input
for (int i = 0; i < prerequisites.size(); ++i)
{
int u = prerequisites[i].first;
int v = prerequisites[i].second;
vertex.insert(u);
vertex.insert(v);
if (edges.find(u) != edges.end())
{
edges[u].insert(v);
}
else
{
set<int> nextVertice;
nextVertice.insert(v);
edges[u] = nextVertice;
}
}
//pre handle
for (auto currentVertice : vertex)
{
visited[currentVertice] = false;
}
//dfs
for (auto currentVertice : vertex)
{
visit(currentVertice);
}
//check backedge
for (int i = 0; i < prerequisites.size(); ++i)
{
int u = prerequisites[i].first;
int v = prerequisites[i].second;
cout << "u " << preClock[u] << " : " << postClock[u] << endl;
cout << "v " << preClock[v] << " : " << postClock[v] << endl << endl;
if (preClock[v] < preClock[u] && postClock[v] > postClock[u])
{
//has backedge
return false;
}
}
return true;
}
void preVisit(int currentVertice)
{
preClock[currentVertice] = clock;
clock++;
}
void postVisit(int currentVertice)
{
postClock[currentVertice] = clock;
clock++;
}
void visit(int currentVertice)
{
if (visited[currentVertice])
return;
visited[currentVertice] = true;
preVisit(currentVertice);
for (auto nextVertice : edges[currentVertice])
{
visit(nextVertice);
}
postVisit(currentVertice);
}
private:
int clock;
map<int, int> preClock;
map<int, int> postClock;
map<int, bool> visited;
map< int, set<int> > edges;
set< int > vertex;
};