// stdafx.h : 标准系统包含文件的包含文件,
// 或是经常使用但不常更改的
// 特定于项目的包含文件
//
#pragma once
#include "targetver.h"
#include <stdio.h>
#include <tchar.h>
#include<iostream>
#include<string>
#include<vector>
#include<cmath>
#include<map>
#include<set>
#include<algorithm>
#include<iterator>
#include<unordered_map>
#include<iomanip>
#include<typeinfo>
// TODO: 在此处引用程序需要的其他头文件
// aiqiyi.cpp: 定义控制台应用程序的入口点。
//
#include "stdafx.h"
using namespace std;
int times = 0;
class Node
{
public:
int val;
Node* parent;
vector<Node*> next;
int color;
int start_time;
int end_time;
Node(int val_char, Node* par, vector<Node*> nex, int col, int sta_t, int end_t) :
val(val_char), parent(par), next(nex), color(col), start_time(sta_t), end_time(end_t) {}
};
void DFS_VISIT(vector<vector<Node*>>& node_next, vector<Node*>& node_set, int target)
{
times++;
node_set[target]->start_time = times;
node_set[target]->color = 1;
for (int i = 0; i < node_next[target].size(); ++i)
{
if ((node_next[target][i])->color == 0)
{
(node_next[target][i])->parent = node_set[target];
DFS_VISIT(node_next, node_set, node_next[target][i]->val-'q');
}
}
times++;
node_set[target]->end_time = times;
}
void DFS(vector<vector<Node*>>& node_next, vector<Node*>& node_set)
{
for (int i = 0; i < 10; ++i)
{
if ((node_set[i])->color == 0)
DFS_VISIT(node_next, node_set, i);
}
}
int main()
{
vector<vector<Node*> >node_next(10,vector<Node*>(0));
vector<Node*> node_set;
for (int i = 0; i < 10; ++i)
{
auto temp = new Node('q' + i, NULL, node_next[i], 0, 0, 0);
node_set.push_back(temp);
}
(node_next[0]).push_back(node_set[2]);
(node_next[0]).push_back(node_set[3]);
(node_next[0]).push_back(node_set[6]);
(node_next[1]).push_back(node_set[4]);
(node_next[1]).push_back(node_set[8]);
(node_next[2]).push_back(node_set[5]);
(node_next[3]).push_back(node_set[7]);
(node_next[3]).push_back(node_set[8]);
(node_next[4]).push_back(node_set[8]);
(node_next[5]).push_back(node_set[6]);
node_next[6].push_back(node_set[2]);
(node_next[7]).push_back(node_set[9]);
(node_next[8]).push_back(node_set[0]);
(node_next[9]).push_back(node_set[7]);
DFS(node_next,node_set);
for (int i = 0; i < 10; i++)
cout << node_set[i]->start_time<<" "<<node_set[i]->end_time << endl;
return 0;
}
void DFS_noncursion(vector<vector<Node*>>& node_next, vector<Node*>& node_set)
{
stack<Node*> node_stack;
node_stack.push(node_set[0]);
int iter = 0;
while (iter < 10)
{
if (node_stack.empty())
{
while (iter < 10 && node_set[iter]->color)
++iter;
if (iter >= 10)
break;
node_stack.push(node_set[iter]);
}
else
{
while (!node_stack.empty())
{
auto top_rank = (node_stack.top())->val;
if (node_set[top_rank - 'q']->color == 0)
{
times++;
node_set[top_rank - 'q']->start_time = times;
node_set[top_rank - 'q']->color = 1;
}
int sign = 1;
for (int j = 0; j < node_next[top_rank - 'q'].size(); ++j)
{
if (node_next[top_rank - 'q'][j]->color == 0)
{
cout << char(node_next[top_rank - 'q'][j]->val) << endl;
node_next[top_rank - 'q'][j]->parent = node_set[top_rank - 'q'];
node_stack.push(node_next[top_rank - 'q'][j]);
sign = 0;
break;
}
}
if (sign)
{
times++;
node_set[top_rank - 'q']->end_time = times;
node_stack.pop();
}
}
}
}
}
以下为尝试用CLRS上的DFS与拓扑排序检查有向图中是否存在环。
// aiqiyi.cpp: 定义控制台应用程序的入口点。
//
#include "stdafx.h"
using namespace std;
static int times = 0;
static bool sign = 0;
class Node
{
public:
int val;
int parent;
vector<Node*> next;
int color;
int start_time;
int end_time;
Node(int val_char, int par, vector<Node*> nex, int col, int sta_t, int end_t) :
val(val_char), parent(par), next(nex), color(col), start_time(sta_t), end_time(end_t) {}
};
int find_index(vector<Node*>& node_set, int targets)
{
for (int ind = 0; ind < node_set.size(); ++ind)
{
if (node_set[ind]->val == targets)
return ind;
}
}
int DFS_VISIT(vector<vector<Node*>> node_next, vector<Node*> node_set, int targets)//targets is the value of node!!
{
times++;
int target = find_index(node_set, targets);
node_set[target]->start_time = times;
node_set[target]->color = 1;
for (int i = 0; i < node_next[target].size(); ++i)
{
if ((node_next[target][i])->color == 0)
{
if (sign)
return 1;
(node_next[target][i])->parent = node_set[target]->val;
DFS_VISIT(node_next, node_set, node_next[target][i]->val);
}
}
times++;
node_set[target]->end_time = times;
return 0;
}
int DFS(vector<vector<Node*>> node_next, vector<Node*> node_set)
{
for (int i = 0; i < node_set.size(); ++i)
{
if ((node_set[i])->color == 0)
{
if (DFS_VISIT(node_next, node_set, node_set[i]->val))
return 1;
}
}
return 0;
}
static const bool Less(const int &a, const int & b)
{
return a >= b;
}
bool canFinish(int numCourses, vector<pair<int, int>>& prerequisites)
{
vector<vector<Node*> >node_next(numCourses, vector<Node*>(0));
vector<Node*> node_set;
vector<vector<Node*> >node_next_T(numCourses, vector<Node*>(0));
vector<Node*> node_set_T;
for (int i = 0; i < numCourses; ++i)
{
auto temp = new Node(i, 0, node_next[i], 0, 0, 0);
auto temp_T = new Node(i, 0, node_next_T[i], 0, 0, 0);;
node_set.push_back(temp);
node_set_T.push_back(temp_T);
}
int pair_len = prerequisites.size();
for (int i = 0; i < pair_len; ++i)//to generate the graph
{
node_next[prerequisites[i].first].push_back(node_set[prerequisites[i].second]);
node_next_T[prerequisites[i].second].push_back(node_set_T[prerequisites[i].first]);
}
for (int i = 0; i < numCourses; ++i)
{
node_set[i]->next = node_next[i];
node_set_T[i]->next = node_next_T[i];
}
//we need to check if it's an DAG first--to check if there exists a strongly-connectedly-component
DFS(node_next,node_set);
//to record the finish time of each node_visit in the first round of DFS;the info is useful for the next round DFS
vector<int>fin_time;
for (int i = 0; i < numCourses; ++i)
fin_time.push_back(node_set[i]->end_time);
//release memory!!!
vector<Node*>().swap(node_set);
vector<vector<Node*>>().swap(node_next);
//to compare the vector before and after sort, then you'll know the rank of numbers in the vector
//here maybe you can use priority queue
vector<int>fin_time_I = fin_time;
sort(fin_time.begin(), fin_time.end(),Less);
vector<int>index;
for (int i = 0; i < numCourses; ++i)
{
index.push_back(find(fin_time_I.begin(),fin_time_I.end(),fin_time[i])-fin_time_I.begin());
}
//sort node_set_T and node_next_T in the visiting order
vector<vector<Node*> >node_next_R;
vector<Node*>node_set_R;
for (int i = 0; i < numCourses; ++i)
{
node_set_R.push_back(node_set_T[index[i]]);
node_next_R.push_back(node_next_T[index[i]]);
}
sign = 1;
times = 0;
int res = !DFS(node_next_R, node_set_R);
//for (int i = 0; i < numCourses; ++i)
//{
// cout <<"node_num:"<< node_set_R[i]->val<<" sta:"<< node_set_R[i]->start_time<<" end:"<<node_set_R[i]->end_time << endl;
//}
for (int i = 0; i < numCourses; ++i)
delete node_set_T[i];
vector<Node*>().swap(node_set_T);
vector<Node*>().swap(node_set_R);
vector<vector<Node*>>().swap(node_next_T);
vector<vector<Node*>>().swap(node_next_R);
return res;
}
int main()
{
vector<pair<int, int>> pre;
//pre.push_back({ 2,1 });
pre.push_back({ 1,0 });
//pre.push_back({ 0,2 });
cout<<canFinish(2, pre)<<endl;
return 0;
}