圖類題目常規解法—Leetcode-thinking_record09

圖的定義

圖的構造與表示

鄰接矩陣表示法

代碼實現

#include <stdio.h>

int main(){
	const int MAX_N = 5;
	int Graph[MAX_N][MAX_N] = {0};
	Graph[0][2] = 1;
	Graph[0][4] = 1;
	Graph[1][0] = 1;
	Graph[1][2] = 1;
	Graph[2][3] = 1;
	Graph[3][4] = 1;
	Graph[4][3] = 1;
	printf("Graph:\n");
	for (int i = 0; i < MAX_N; i++){
		for (int j = 0; j < MAX_N; j++){
			printf("%d ", Graph[i][j]);
		}
		printf("\n");
	}
	return 0;
}

鄰接表表示法

代碼實現

#include <stdio.h>
#include <vector>

struct GraphNode{
	int label;
	std::vector<GraphNode *> neighbors;
	GraphNode(int x) : label(x) {};
};

int main(){	
	const int MAX_N = 5;
	GraphNode *Graph[MAX_N];
	
	for (int i = 0; i < MAX_N; i++){
		Graph[i] = new GraphNode(i);
	}
	
	Graph[0]->neighbors.push_back(Graph[2]);
	Graph[0]->neighbors.push_back(Graph[4]);
	Graph[1]->neighbors.push_back(Graph[0]);
	Graph[1]->neighbors.push_back(Graph[2]);
	Graph[2]->neighbors.push_back(Graph[3]);
	Graph[3]->neighbors.push_back(Graph[4]);
	Graph[4]->neighbors.push_back(Graph[3]);
	
	printf("Graph:\n");
	for (int i = 0; i < MAX_N; i++){
		printf("Label(%d) : ", i);
		for (int j = 0; j < Graph[i]->neighbors.size(); j++){
			printf("%d ", Graph[i]->neighbors[j]->label);
		}
		printf("\n");
	}
	
	for (int i = 0; i < MAX_N; i++){
		delete Graph[i];
	}
	
	return 0;
}

圖的兩大經典遍歷

深度優先遍歷

代碼實現

 

#include <stdio.h>
#include <vector>

struct GraphNode{
	int label;
	std::vector<GraphNode *> neighbors;
	GraphNode(int x) : label(x) {};
};

void DFS_graph(GraphNode *node, int visit[]){
	visit[node->label] = 1;
	printf("%d ", node->label);
	for (int i = 0; i < node->neighbors.size(); i++){
		if (visit[node->neighbors[i]->label] == 0){
			DFS_graph(node->neighbors[i], visit);
		}
	}
} 

int main(){
	const int MAX_N = 5;
	GraphNode *Graph[MAX_N];	
	for (int i = 0; i < MAX_N; i++){
		Graph[i] = new GraphNode(i);
	}
	
	Graph[0]->neighbors.push_back(Graph[4]);
	Graph[0]->neighbors.push_back(Graph[2]);	
	Graph[1]->neighbors.push_back(Graph[0]);
	Graph[1]->neighbors.push_back(Graph[2]);
	Graph[2]->neighbors.push_back(Graph[3]);
	Graph[3]->neighbors.push_back(Graph[4]);
	Graph[4]->neighbors.push_back(Graph[3]);
	
	int visit[MAX_N] = {0};
	for (int i = 0; i < MAX_N; i++){
		if (visit[i] == 0){
			printf("From label(%d) : ", Graph[i]->label);
			DFS_graph(Graph[i], visit);
			printf("\n");
		}
	}
	
	for (int i = 0; i < MAX_N; i++){
		delete Graph[i];
	}
	
	return 0;
}

寬度優先遍歷 

代碼實現

#include <stdio.h>
#include <vector>
#include <queue>

struct GraphNode{
	int label;
	std::vector<GraphNode *> neighbors;
	GraphNode(int x) : label(x) {};
};

void BFS_graph(GraphNode *node, int visit[]){
	std::queue<GraphNode *> Q;
	Q.push(node);
	visit[node->label] = 1;
	while(!Q.empty()){
		GraphNode *node = Q.front();
		Q.pop();
		printf("%d ", node->label);
		for (int i = 0; i < node->neighbors.size(); i++){
			if (visit[node->neighbors[i]->label] == 0){
				Q.push(node->neighbors[i]);
				visit[node->neighbors[i]->label] = 1;
			}
		}
	}
}

int main(){
	const int MAX_N = 5;
	GraphNode *Graph[MAX_N];
	for (int i = 0; i < MAX_N; i++){
		Graph[i] = new GraphNode(i);
	}
	
	Graph[0]->neighbors.push_back(Graph[4]);
	Graph[0]->neighbors.push_back(Graph[2]);
	Graph[1]->neighbors.push_back(Graph[0]);
	Graph[1]->neighbors.push_back(Graph[2]);
	Graph[2]->neighbors.push_back(Graph[3]);
	Graph[3]->neighbors.push_back(Graph[4]);
	Graph[4]->neighbors.push_back(Graph[3]);
	
	int visit[MAX_N] = {0};
	for (int i = 0; i < MAX_N; i++){
		if (visit[i] == 0){
			printf("From label(%d) : ", Graph[i]->label);
			BFS_graph(Graph[i], visit);
			printf("\n");
		}
	}
	
	for (int i = 0; i < MAX_N; i++){
		delete Graph[i];
	}
	
	return 0;
}

課程安排

已知有n個課程,標記從0至n-1,課程之間是有依賴關係的,例如希望完成A課程,可能需要先完成B課程。已知n個課程的依賴關係,求是否可以將n個課程全部完成。

LeetCode 207.Course Schedule

Solve1:深度優先搜索

總體思路

細節設計 

無環情況:

 有環情況:

代碼實現 

#include <stdio.h>

#include <vector>
struct GraphNode{
	int label;
	std::vector<GraphNode *> neighbors;
	GraphNode(int x) : label(x) {};
};
bool DFS_graph(GraphNode *node, std::vector<int> &visit){
	visit[node->label] = 0;
	for (int i = 0; i < node->neighbors.size(); i++){
		if (visit[node->neighbors[i]->label] == -1){
			if (DFS_graph(node->neighbors[i], visit) == 0){
				return false;
			}
		}
		else if (visit[node->neighbors[i]->label] == 0){
			return false;
		}
	}
	visit[node->label] = 1;
	return true;
}

class Solution {
public:
    bool canFinish(int numCourses,
		std::vector<std::pair<int, int> >& prerequisites) {
		std::vector<GraphNode*> graph;
		std::vector<int> visit;
		for (int i = 0; i < numCourses; i++){
			graph.push_back(new GraphNode(i));
			visit.push_back(-1);
		}
		for (int i = 0; i < prerequisites.size(); i++){
			GraphNode *begin = graph[prerequisites[i].second];
			GraphNode *end = graph[prerequisites[i].first];
			begin->neighbors.push_back(end);
		}
		for (int i = 0; i < graph.size(); i++){
			if (visit[i] == -1 && !DFS_graph(graph[i], visit)){
				return false;
			}
		}
		for (int i = 0; i < numCourses; i++){
			delete graph[i];
		}
		return true;
    }
};

int main(){	
	std::vector<std::pair<int, int> > prerequisites;
	prerequisites.push_back(std::make_pair(1, 0));
	prerequisites.push_back(std::make_pair(2, 0));
	prerequisites.push_back(std::make_pair(3, 1));
	prerequisites.push_back(std::make_pair(3, 2));
	Solution solve;
	printf("%d\n", solve.canFinish(4, prerequisites));
	return 0;
}

Solve2:寬度優先搜索(拓撲排序)

總體思路

細節設計

無環情況:

有環情況:

代碼實現

#include <stdio.h>

#include <vector>
#include <queue>

struct GraphNode{
	int label;
	std::vector<GraphNode *> neighbors;
	GraphNode(int x) : label(x) {};
};

class Solution {
public:
    bool canFinish(int numCourses,
		std::vector<std::pair<int, int> >& prerequisites) {
		std::vector<GraphNode*> graph;
		std::vector<int> degree;
		for (int i = 0; i < numCourses; i++){
			degree.push_back(0);
			graph.push_back(new GraphNode(i));
		}
		for (int i = 0; i < prerequisites.size(); i++){
			GraphNode *begin = graph[prerequisites[i].second];
			GraphNode *end = graph[prerequisites[i].first];
			begin->neighbors.push_back(end);
			degree[prerequisites[i].first]++;
		}		
		std::queue<GraphNode *> Q;
		for (int i = 0; i < numCourses; i++){
			if (degree[i] == 0){
				Q.push(graph[i]);
			}
		}
		while(!Q.empty()){
			GraphNode *node = Q.front();
			Q.pop();
			for (int i = 0; i < node->neighbors.size(); i++){
				degree[node->neighbors[i]->label]--;
				if (degree[node->neighbors[i]->label] == 0){
					Q.push(node->neighbors[i]);
				}
			}
		}		
		for (int i = 0; i < graph.size(); i++){
			delete graph[i];
		}		
		for (int i = 0; i < degree.size(); i++){
			if (degree[i]){
				return false;
			}
		}
		return true;
    }
};

int main(){	
	std::vector<std::pair<int, int> > prerequisites;
	prerequisites.push_back(std::make_pair(1, 0));
	prerequisites.push_back(std::make_pair(2, 0));
	prerequisites.push_back(std::make_pair(3, 1));
	prerequisites.push_back(std::make_pair(3, 2));
	Solution solve;
	printf("%d\n", solve.canFinish(4, prerequisites));	
	return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章