CLRS 22.3-2,7 邻接表实现

// 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;
}


猜你喜欢

转载自blog.csdn.net/georgeandgeorge/article/details/80419323