程序设计代码 贴着玩。。七
来源:互联网 发布:百度电影推荐系统算法 编辑:程序博客网 时间:2024/05/16 07:21
图类的实现
两种存储结构的邻接矩阵和邻接链表存储的都实现了,实现了图类的大部分算法
#ifndef GRAPH_H_INCLUDED#define GRAPH_H_INCLUDED#include<cstdio>#include<iostream>#include<algorithm>#include<stack>#include<cstring>#include<string>#include<queue>const int MAX_V = 100;///图最多有一百个顶点const int MAX_W = 1000;///边的权重最多为1000class Graph{public: ///I. 构造函数与析构函数Graph( ) {}virtual ~Graph( ) {} ///II. 图的维护函数 virtual int GraphEmpty(void) const = 0; ///检测图是否为空virtual int GraphFull(void) const = 0;; ///检测图是否已满,即顶点个数是否越界virtual int NumberOfVertices( void ) const = 0;///返回图的顶点个数virtual int NumberOfEdges( void ) const = 0; ///返回图的边个数 virtual int GetWeight( const int v1, const int v2 ) = 0; /// 返回指定边的权值virtual int* GetNeighbors( const int v ) = 0;/// 返回顶点v的邻接顶点表 virtual int GetFirstNeighbor( const int v ) = 0; /// 返回序号为v的顶点的第一个邻接顶点的序号 virtual int GetNextNeighbor( const int v1, const int v2 ) = 0; ///返回序号为v1的顶点相对于序号为v2的顶点的下一个邻接顶点的序号virtual void InsertVertex( const int & v) = 0; /// 向图中插入一个顶点virtual void InsertEdge(const int & v1, const int & v2, int weight) = 0; ///向图中插入一条边virtual void DeleteVertex( const int & v ) = 0; ///从图中删除一个顶点virtual void DeleteEdge( const int & v1, const int & v2 ) = 0; ///从图中删除一条边 /// III. 图的基本算法 virtual void DepthFirstSearch() = 0;///图的深度优先搜索(递归) virtual void RDFS(int u, int visited[]) = 0; virtual void DFS(const int v) = 0; ///从顶点v开始进行图的深度优先搜索(迭代方法) virtual void BFS( const int v ) = 0; ///从顶点v开始进行图的广度优先搜索 virtual void TopoOrder( ) = 0; /// 图的拓扑排序 virtual void CriticalPath( ) = 0; /// 输出图的关键路径 virtual void ShortestPath(const int v ) = 0; /// 求无权图中顶点v到其他顶点的最短路径 virtual void DShortestPath(const int v ) = 0; /// 求正权图中顶点v到其他顶点的最短路径 virtual void AllLength( ) = 0; /// 求正权图中每对顶点间的最短路径 virtual void Prim(int u0 ) = 0; /// 构造图的最小支撑树的普里姆算法};class Graph_Matrix:public Graph{private: int num_v;///顶点个数 int num_e;///边的个数 int Edge[MAX_V][MAX_V];public: ///II. 图的维护函数 Graph_Matrix(FILE *fp); virtual int GraphEmpty(void) const; ///检测图是否为空virtual int GraphFull(void) const ; ///检测图是否已满,即顶点个数是否越界virtual int NumberOfVertices( void ) const ;///返回图的顶点个数virtual int NumberOfEdges( void ) const ; ///返回图的边个数 virtual int GetWeight( const int v1, const int v2 ) ; /// 返回指定边的权值virtual int* GetNeighbors( const int v ) ;/// 返回顶点v的邻接顶点表 virtual int GetFirstNeighbor( const int v ) ; /// 返回序号为v的顶点的第一个邻接顶点的序号 virtual int GetNextNeighbor( const int v1, const int v2 ) ; ///返回序号为v1的顶点相对于序号为v2的顶点的下一个邻接顶点的序号virtual void InsertVertex( const int & v) ; /// 向图中插入一个顶点virtual void InsertEdge(const int & v1, const int & v2, int weight);virtual void DeleteVertex( const int & v ) ; ///从图中删除一个顶点virtual void DeleteEdge( const int & v1, const int & v2 ) ; ///从图中删除一条边 /// III. 图的基本算法 virtual void DepthFirstSearch() ;///图的深度优先搜索(递归) virtual void RDFS(int u, int visited[]); virtual void DFS(const int v) ; ///从顶点v开始进行图的深度优先搜索(迭代方法) virtual void BFS( const int v ) ; ///从顶点v开始进行图的广度优先搜索 virtual void TopoOrder( ) ; /// 图的拓扑排序 virtual void CriticalPath( ) ; /// 输出图的关键路径 virtual void ShortestPath(const int v ) ; /// 求无权图中顶点v到其他顶点的最短路径 virtual void DShortestPath(const int v ) ; /// 求正权图中顶点v到其他顶点的最短路径 virtual void AllLength( ) ; /// 求正权图中每对顶点间的最短路径 virtual void Prim(int u0 ) ; /// 构造图的最小支撑树的普里姆算法};struct Edge{ int VerAdj;///边的另一个结点的边号 int weight;///边的权值 Edge *next;///下一个边结点的指针};struct Vertex{ int num;///顶点的编号 Edge *head1;///出边链表的头指针 Edge *head2;///入边链表的头指针};class Graph_Link:public Graph{private: int num_v, num_e; Vertex Head[MAX_V];public: Graph_Link(FILE *fp); ///II. 图的维护函数 virtual int GraphEmpty(void) const ;///检测图是否为空virtual int GraphFull(void) const ; ///检测图是否已满,即顶点个数是否越界virtual int NumberOfVertices( void ) const ;///返回图的顶点个数virtual int NumberOfEdges( void ) const ; ///返回图的边个数 virtual int GetWeight( const int v1, const int v2 ) ; /// 返回指定边的权值virtual int* GetNeighbors( const int v ) ;/// 返回顶点v的邻接顶点表 virtual int GetFirstNeighbor( const int v ) ; /// 返回序号为v的顶点的第一个邻接顶点的序号 virtual int GetNextNeighbor( const int v1, const int v2 ) ; ///返回序号为v1的顶点相对于序号为v2的顶点的下一个邻接顶点的序号virtual void InsertVertex( const int & v) ; /// 向图中插入一个顶点virtual void InsertEdge(const int& v1, const int& v2, int weight);///想图中加入一条边virtual void DeleteVertex( const int & v ) ; ///从图中删除一个顶点virtual void DeleteEdge( const int & v1, const int & v2 ) ; ///从图中删除一条边 /// III. 图的基本算法 virtual void DepthFirstSearch() ;///图的深度优先搜索(递归) virtual void RDFS(int u, int visited[]); virtual void DFS(const int v) ; ///从顶点v开始进行图的深度优先搜索(迭代方法) virtual void BFS( const int v ) ; ///从顶点v开始进行图的广度优先搜索 virtual void TopoOrder( ) ; /// 图的拓扑排序 virtual void CriticalPath( ) ; /// 输出图的关键路径 virtual void ShortestPath(const int v ) ; /// 求无权图中顶点v到其他顶点的最短路径 virtual void DShortestPath(const int v ) ; /// 求正权图中顶点v到其他顶点的最短路径 virtual void AllLength( ) ; /// 求正权图中每对顶点间的最短路径 virtual void Prim( int u0) ; /// 构造图的最小支撑树的普里姆算法};#endif // GRAPH_H_INCLUDED
#include"Graph.h"#include<cstdio>#include<iostream>#include<algorithm>#include<cstring>#include<string>#include<stack>#include<queue>using namespace std;Graph_Matrix::Graph_Matrix(FILE *fp) { printf("请输入所构造图的顶点个数以及边的个数\n"); int v, e; fscanf(fp, "%d%d", &v, &e); num_v = v; num_e = e; printf("请输入所要构造的图的边的信息\n"); for(int i = 0; i < v; ++ i) { for(int j = 0; j < v; ++ j) { if(i == j) { Edge[i][j] = 0; } else { Edge[i][j] = MAX_W; } } } int f, t, w; for(int i = 0; i < e; ++ i) { fscanf(fp, "%d %d %d", &f, &t, &w); Edge[f][t] = w; }}int Graph_Matrix::GraphEmpty(void) const{ if(num_v == 0) { return 1; } return 0;}int Graph_Matrix::GraphFull(void) const{ if(num_v == MAX_V) { return 1; } return 0;}int Graph_Matrix::NumberOfVertices(void) const { return num_v;}int Graph_Matrix::NumberOfEdges() const { return num_e;}int Graph_Matrix::GetWeight(const int v1, const int v2) { return Edge[v1][v2];}int* Graph_Matrix::GetNeighbors(const int v) { int cnt = 0; int neighbor[num_v]; memset(neighbor, -1, sizeof(neighbor)); for(int i = 0; i < num_v; ++ i) { if(Edge[v][i] != 0) { neighbor[cnt++] = i; } } return neighbor;}int Graph_Matrix::GetFirstNeighbor(const int v) { int cnt = 0; for(int i = 0; i < num_v; ++ i) { if(Edge[v][i] != 0) { return i; } } return -1;}int Graph_Matrix::GetNextNeighbor(const int v1, const int v2) { for(int i = 0; i < num_v; ++ i) { if(i != v2 && Edge[v1][i] != MAX_W) { return i; } } return -1;}void Graph_Matrix::InsertVertex(const int& v) { if(GraphFull()) { cout<<"图已满,无法再插入"<<endl; return ; } num_v++;}void Graph_Matrix::InsertEdge(const int& v1, const int& v2, int weight) { Edge[v1][v2] = weight;}void Graph_Matrix::DeleteVertex(const int& v) { for(int i = 0; i < num_v; ++ i) { Edge[i][v] = Edge[v][i] = MAX_W; } num_v--;}void Graph_Matrix::DeleteEdge(const int& v1, const int& v2) { Edge[v1][v2] = MAX_W;}void Graph_Matrix::RDFS(int u, int visited[]) { for(int i = 1; i < num_v; ++ i) { if(!visited[i] && Edge[u][i] < MAX_W) { visited[i] = 1; cout<<" "<<i; RDFS(i, visited); } }}void Graph_Matrix::DepthFirstSearch() { int visited[num_v]; memset(visited, 0, sizeof(visited)); visited[0] = 1; cout<<0; RDFS(0, visited); cout<<endl;}void Graph_Matrix::DFS(int v) { stack<int>s; int visited[num_v]; for(int i = 0; i < num_v; ++ i) { visited[i] = 0; } s.push(v); visited[v] = 1; while(!s.empty()) { int t = s.top(); cout<<t<<" "; s.pop(); for(int i = 0; i < num_v; ++ i) { if(Edge[t][i] != MAX_W && !visited[i]) { s.push(i); visited[i] = 1; } } } cout<<endl;}void Graph_Matrix::BFS(int v) { queue<int>q; q.push(v); int visited[num_v]; for(int i = 0; i < num_v; ++ i) { visited[i] = 0; } visited[v] = 1; while(!q.empty()) { int f = q.front(); cout<<f<<" "; q.pop(); for(int i = 0; i < num_v; ++ i) { if(Edge[f][i] != 0 && !visited[i]) { q.push(i); visited[i] = 1; } } } cout<<endl;}void Graph_Matrix::TopoOrder() { int indeg[num_v]; memset(indeg, 0, sizeof(indeg)); for(int i = 0; i < num_v; ++ i) { for(int j = 0; j < num_v; ++ j) { if(i != j && Edge[j][i] != MAX_W) { indeg[i]++; } } //cout<<indeg[i]<<" "; } cout<<endl; int top = 0; stack<int>s; int visited[num_v]; memset(visited, 0, sizeof(visited)); for(int i = 0; i < num_v; ++ i) { if(indeg[i] == 0) { s.push(i); visited[i] = 1; } } while(!s.empty()) { int j = s.top(); s.pop(); cout<<j<<" "; top++; for(int k = 0; k < num_v; ++ k) { if(Edge[j][k] != MAX_W) { indeg[k]--; if(indeg[k] == 0 && !visited[k]) { s.push(k); visited[k] = 1; } } } } if(top != num_v) { printf("图中存在环\n"); } else { printf("\n拓扑排序完成"); }}void Graph_Matrix::CriticalPath() { int topoorder[num_v]; int indeg[num_v]; int ve[num_v]; int vl[num_v]; memset(indeg, 0, sizeof(indeg)); for(int i = 0; i < num_v; ++ i) { for(int j = 0; j < num_v; ++ j) { if(i != j && Edge[j][i] != MAX_W) { indeg[i]++; } } } int top = 0; stack<int>s; int visited[num_v]; memset(visited, 0, sizeof(visited)); for(int i = 0; i < num_v; ++ i) { if(indeg[i] == 0) { s.push(i); visited[i] = 1; } } while(!s.empty()) { int j = s.top(); s.pop(); topoorder[top] = j; top++; for(int k = 0; k < num_v; ++ k) { if(Edge[j][k] != MAX_W) { indeg[k]--; if(indeg[k] == 0 && !visited[k]) { s.push(k); visited[k] = 1; } } } } if(top != num_v) { printf("图中存在环无法寻找关键路径"); return; } ve[topoorder[0]] = 0; for(int i = 1; i < num_v; ++ i) { int max = 0, temp; for(int j = 0; j < i; ++ j) { if(Edge[topoorder[j]][topoorder[i]] != MAX_W) { temp = ve[topoorder[j]] + Edge[topoorder[j]][topoorder[i]]; if(temp > max) { max = temp; } } } ve[topoorder[i]] = max; } vl[topoorder[num_v - 1]] = ve[topoorder[num_v - 1]]; for(int i = num_v - 2; i >= 0; -- i) { int min = vl[topoorder[num_v - 1]], temp; for(int j = num_v - 1; j > i; -- j) { if(Edge[topoorder[i]][topoorder[j]] != MAX_W) { temp = vl[topoorder[j]] - Edge[topoorder[i]][topoorder[j]]; if(temp < min) { min = temp; } } } vl[topoorder[i]] = min; } for(int i = 0; i < num_v; ++ i) { for(int j = i + 1; j < num_v; ++ j) { if(Edge[topoorder[i]][topoorder[j]] != MAX_W) { if(ve[topoorder[i]] == vl[topoorder[j]] - Edge[topoorder[i]][topoorder[j]]) { printf("<%d, %d>是关键路径\n", topoorder[i], topoorder[j]); } } } }}void Graph_Matrix::ShortestPath(const int v) { int dist[num_v]; int path[num_v]; for(int i = 0; i < num_v; ++ i) { dist[i] = -1; path[i] = -1; } dist[v] = 0; queue<int>q; q.push(v); while(!q.empty()) { int f = q.front(); q.pop(); for(int i = 0; i < num_v; ++ i) { if(dist[i] == -1 && Edge[f][i] != MAX_W) { q.push(i); dist[i] = dist[f] + 1; path[i] = f; } } } int result[num_v]; for(int i = 0; i < num_v; ++ i) { if(dist[i] == -1) { cout<<"从点"<<v<<"到点"<<i<<"不存在路径"<<endl; } else { cout<<"从点"<<v<<"到点"<<i<<"的路径长度为:"<<dist[i]<<endl; int cnt = 0; result[cnt ++ ] = i; int a = i; while(path[a] != -1) { result[cnt++] = path[a]; a = path[a]; } cout<<"最短路径为"; for(int i = cnt - 1; i >= 0; -- i) { if(i == cnt - 1) { printf("%d", result[i]); } else { printf("->%d", result[i]); } } printf("\n"); } }}void Graph_Matrix::DShortestPath(int u) { int path[num_v]; int s[num_v]; int dist[num_v]; for(int i = 0; i < num_v; ++ i) { dist[i] = Edge[u][i]; s[i] = 0; if(i != u && dist[u] < MAX_W ) { path[i] = u; } else { path[i] = -1; } } s[u] = 1; for(int i = 1; i < num_v; ++ i) { int min = MAX_W, v = u; for(int j = 0; j < num_v; ++ j) { if(!s[j] && dist[j] < MAX_W) { v = j; min = dist[j]; } } s[v] = 1; for(int j = 0; j < num_v; ++ j) { if(!s[j] && Edge[v][j] < MAX_W && dist[v] + Edge[v][j] < dist[j]) { dist[j] = dist[v] + Edge[v][j]; path[j] = v; } } } int result[num_v]; for(int i = 0; i < num_v; ++ i) { if(dist[i] == -1) { cout<<"从点"<<u<<"到点"<<i<<"不存在路径"<<endl; } else { cout<<"从点"<<u<<"到点"<<i<<"的加权路径长度为:"<<dist[i]<<endl; int cnt = 0; int a = i; result[cnt ++ ] = i; while(path[a] != -1) { result[cnt++] = path[a]; a = path[a]; } cout<<"最短路径为"; for(int j = cnt - 1; j >= 0; -- j) { if(j != cnt - 1) { cout<<"->"<<result[j]; } else { cout<<result[j]; } } cout<<endl; } }}void Graph_Matrix::AllLength() { int floyd[num_v][num_v]; int path[num_v][num_v]; for(int i = 0; i < num_v; ++ i) { for(int j = 0; j < num_v; ++ j) { floyd[i][j] = Edge[i][j]; if(i != j && floyd[i][j] < MAX_W) { path[i][j] = i; } else { path[i][j] = -1; } } } for(int k = 0; k < num_v; ++ k) { for(int i = 0; i < num_v; ++ i) { if(i != k) { for(int j = 0; j < num_v; ++ j) { if(j != k && j != i && floyd[i][k] < MAX_W && floyd[k][j] < MAX_W) { if(floyd[i][k] + floyd[k][j] < floyd[i][j]) { floyd[i][j] = floyd[i][k] + floyd[k][j]; path[i][j] = path[k][j]; } } } } } } for(int i = 0; i < num_v; ++ i) { for(int j = 0; j < num_v; ++ j) { if(i == j) { continue; } if(floyd[i][j] < MAX_W ) { cout<<"从点"<<i<<"到点"<<j<<"加权最短路径长度为:"<<floyd[i][j]<<endl; cout<<"最短路径为:"; int result[num_v]; memset(result, 0, sizeof(result)); int cnt = 0; result[cnt] = j; while(path[i][result[cnt]] != i) { cnt ++ ; result[cnt] = path[i][result[cnt - 1]]; } cnt ++ ; result[cnt] = i; for(int k = cnt; k > 0; -- k) { cout<<result[k]<<"->"; } cout<<result[0]<<endl; } else { cout<<"从点"<<i<<"到点"<<j<<"不存在路径"<<endl; } } }}void Graph_Matrix::Prim(int u0) { int sumweight = 0; int lowcost[num_v]; int nearvex[num_v]; for(int i = 0; i < num_v; ++ i) { lowcost[i] = Edge[u0][i]; nearvex[i] = u0; } nearvex[u0] = -1; for(int i = 0; i < num_v; ++ i) { int min = MAX_W; int v = -1; for(int j = 0; j < num_v; ++ j) { if(nearvex[j] != -1 && lowcost[j] < min) { min = lowcost[j]; v = j; } } if(v != -1) { printf("%d -> %d 这条边被选中,其权值是 %d\n", nearvex[v], v, lowcost[v]); nearvex[v] = -1; sumweight += lowcost[v]; for(int j = 0; j < num_v; ++ j) { if(nearvex[j] != -1 && Edge[v][j] < lowcost[j]) { lowcost[j] = Edge[v][j]; nearvex[j] = v; } } } } printf("最小生成树的总权值为:%d\n", sumweight);}Graph_Link::Graph_Link(FILE *fp) { cout<<"请输入所要构造的图的顶点个数和边的个数"<<endl; int n, e; fscanf(fp, "%d%d", &n, &e); num_v = n; num_e = e; for(int i = 0; i < n; ++ i) { Head[i].head1 = Head[i].head2 = NULL; } printf("请输入所要构造的图的边的信息\n"); int u, v, w; for(int i = 0; i < e; ++ i) { fscanf(fp, "%d %d %d", &u, &v, &w); InsertEdge(u, v, w); }}int Graph_Link::GraphEmpty() const { if(num_v == 0) { return 1; } return 0;}int Graph_Link::GraphFull() const { if(num_v == MAX_V) { return 1; } return 0;}int Graph_Link::NumberOfVertices() const { return num_v;}int Graph_Link::NumberOfEdges() const { return num_e;}int Graph_Link::GetWeight(const int u, const int v) { Edge *p = Head[u].head1; while(p -> next != NULL) { p = p -> next; if(p -> VerAdj == v) { return p -> weight; } } return MAX_W;}int* Graph_Link::GetNeighbors(const int u) { int neighbor[num_v]; memset(neighbor, -1, sizeof(neighbor)); Edge *p = Head[u].head1; int cnt = 0; while(p -> next != NULL) { p = p -> next; neighbor[cnt ++] = p -> VerAdj; } return neighbor;}int Graph_Link::GetFirstNeighbor(const int u) { if(Head[u].head1->next != NULL) { return Head[u].head1->next->VerAdj; } return -1;}int Graph_Link::GetNextNeighbor(const int u, const int v) { Edge *p = Head[u].head1; while(p -> next != NULL) { p = p -> next; if(p -> VerAdj == v) { p = p -> next; if(p == NULL) { return -1; } return p -> VerAdj; } } return -1;}void Graph_Link::InsertVertex(const int& v) { if(num_v == MAX_V) { cout<<"图已满无法插入"<<endl; return; } num_v ++;}void Graph_Link::InsertEdge(const int& u, const int& v, int w) { Edge *p = new Edge(); p->VerAdj = v; p->weight = w; p->next = NULL; Edge *q = Head[u].head1; //printf("插入"); if(q == NULL) { Head[u].head1 = p; } else { while(q->next != NULL) { // printf("while循环\n"); q = q->next; } q->next = p; } printf("插入成功\n");}void Graph_Link::DeleteVertex(const int& v) { ///}void Graph_Link::DeleteEdge(const int& u, const int& v) { Edge *p = Head[u].head1, *temp; if(u == v) { printf("请输入两个不同的点"); return; } while(p != NULL) { temp = p; if(p -> VerAdj == v) { temp -> next = p -> next; delete p; } p = p -> next; }}void Graph_Link::RDFS(const int v, int visited[]) { cout<<v<<" "; //visited[v] = 1; Edge *p = Head[v].head1; while(p != NULL) { if(!visited[p->VerAdj]) { RDFS(p->VerAdj, visited); visited[p->VerAdj] = 1; } p = p->next; }}void Graph_Link::DepthFirstSearch() { int visited[num_v]; memset(visited, 0, sizeof(visited)); visited[0] =1; cout<<"深度优先遍历的序列:"; RDFS(0., visited); cout<<endl;}void Graph_Link::DFS(int u) { int visited[num_v]; memset(visited, 0, sizeof(visited)); stack<int>s; s.push(u); visited[u] = 1; int w; Edge *p; cout<<"深度优先遍历的序列:"; while(!s.empty()) { w = s.top(); s.pop(); cout<<w<<" "; p = Head[w].head1; while(p != NULL) { if(!visited[p->VerAdj]) { s.push(p->VerAdj); visited[p->VerAdj] = 1; } p = p->next; } } cout<<endl;}void Graph_Link::BFS(const int u) { int visited[num_v]; memset(visited, 0, sizeof(visited)); visited[u] = 1; queue<int>q; q.push(u); int f; Edge *p; cout<<"宽度优先遍历的序列为:"; while(!q.empty()) { f = q.front(); q.pop(); cout<<f<<" "; p = Head[f].head1; while(p != NULL) { if(!visited[p->VerAdj]) { visited[p->VerAdj] = 1; q.push(p->VerAdj); } p = p->next; } } cout<<endl;}void Graph_Link::TopoOrder() { int count[num_v]; memset(count, 0, sizeof(count)); for(int i = 0; i < num_v; ++ i) { Edge *p = Head[i].head1; while(p != NULL) { count[p->VerAdj] ++; p = p->next; } } stack<int>s; int visited[num_v]; memset(visited, 0, sizeof(visited)); for(int i = 0; i < num_v; ++ i) { if(count[i] == 0) { s.push(i); visited[i] = 1; } } int cnt = 0, top; Edge *p; cout<<"拓扑序列为:"; while(!s.empty()) { top = s.top(); cout<<top<<" "; cnt ++; s.pop(); p = Head[top].head1; while(p != NULL) { if(!visited[p->VerAdj]) { count[p->VerAdj]--; if(count[p->VerAdj] == 0) { s.push(p->VerAdj); visited[p->VerAdj] = 1; } } p = p->next; } } if(cnt != num_v) { cout<<"图中存在环"<<endl; } else { cout<<endl; }}void Graph_Link::CriticalPath() { int count[num_v]; memset(count, 0, sizeof(count)); for(int i = 0; i < num_v; ++ i) { Edge *p = Head[i].head1; while(p != NULL) { count[p->VerAdj] ++; p = p->next; } } stack<int>s; int visited[num_v]; memset(visited, 0, sizeof(visited)); for(int i = 0; i < num_v; ++ i) { if(count[i] == 0) { s.push(i); visited[i] = 1; } } int cnt = 0, top; Edge *p; int topoorder[num_v]; while(!s.empty()) { top = s.top(); topoorder[cnt] = top; cnt ++; s.pop(); p = Head[top].head1; while(p != NULL) { if(!visited[p->VerAdj]) { count[p->VerAdj]--; if(count[p->VerAdj] == 0) { s.push(p->VerAdj); visited[p->VerAdj] = 1; } } p = p->next; } } int ve[num_v]; int vl[num_v]; memset(ve, 0, sizeof(ve)); int k; for(int i = 0; i < num_v; ++ i) { Edge *p = Head[topoorder[i]].head1; while(p != NULL) { k = p->VerAdj; if(ve[topoorder[i]] + p->weight > ve[k]) { ve[k] = ve[topoorder[i]] + p->weight; } p = p->next; } } for(int i = 0; i < num_v; ++ i) { vl[i] = ve[topoorder[num_v - 1]]; } for(int i = num_v - 2; i >= 0; -- i) { Edge *p = Head[topoorder[i]].head1; while(p != NULL) { k = p->VerAdj; if(vl[k] - p->weight < vl[topoorder[i]]) { vl[topoorder[i]] = vl[k] - p->weight; } p = p->next; } } for(int i = 0; i < num_v; ++ i) { Edge *p = Head[i].head1; while(p != NULL) { k = p->VerAdj; if(ve[i] == vl[k] - p->weight) { cout<<'<'<<i<<", "<<k<<'>'<<"是关键路径"<<endl; } p = p->next; } }}void Graph_Link::ShortestPath(const int u) { int path[num_v]; int dist[num_v]; queue<int>q; memset(path, -1, sizeof(path)); memset(dist, -1, sizeof(dist)); dist[u] = 0; q.push(u); int f, k; while(!q.empty()) { f = q.front(); q.pop(); Edge *p = Head[f].head1; while(p != NULL) { k = p->VerAdj; if(dist[k] == -1) { q.push(k); dist[k] = dist[f] + 1; path[k] = f; } p = p->next; } } int result[num_v]; for(int i = 0; i < num_v; ++ i) { if(dist[i] == -1) { cout<<"从点"<<u<<"到点"<<i<<"不存在路径"<<endl; } else { cout<<"从点"<<u<<"到点"<<i<<"的路径长度为:"<<dist[i]<<endl; int cnt = 0; result[cnt ++ ] = i; int a = i; while(path[a] != -1) { result[cnt++] = path[a]; a = path[a]; } cout<<"最短路径为"; for(int i = cnt - 1; i >= 0; -- i) { if(i == cnt - 1) { printf("%d", result[i]); } else { printf("->%d", result[i]); } } printf("\n"); } }}void Graph_Link::DShortestPath(const int u) { int path[num_v]; int dist[num_v]; int s[num_v]; memset(path, -1, sizeof(path)); memset(s, 0, sizeof(s)); memset(dist, -1, sizeof(dist)); int k; Edge *p = NULL; p = Head[u].head1; while(p != NULL) { dist[p->VerAdj] = p->weight; path[p->VerAdj] = u; p = p->next; } dist[u] = 0; s[u] = 1; for(int i = 0; i < num_v; ++ i) { int min = MAX_W; int v = -1; for(int j = 0; j < num_v; ++ j) { if(dist[j] > 0 && dist[j] < min && !s[j]) { v = j; min = dist[j]; } } if(v != -1) { s[v] = 1; p = Head[v].head1; while(p != NULL) { if( !s[p->VerAdj] && (dist[v] + p->weight < dist[p->VerAdj] || dist[p->VerAdj] == -1)) { dist[p->VerAdj] = dist[v] + p->weight; path[p->VerAdj] = v; } p = p->next; } } } int result[num_v]; for(int i = 0; i < num_v; ++ i) { if(dist[i] == -1) { cout<<"从点"<<u<<"到点"<<i<<"不存在路径"<<endl; } else { cout<<"从点"<<u<<"到点"<<i<<"的加权路径长度为:"<<dist[i]<<endl; int cnt = 0; int a = i; result[cnt ++ ] = i; while(path[a] != -1) { result[cnt++] = path[a]; a = path[a]; } cout<<"最短路径为"; for(int j = cnt - 1; j >= 0; -- j) { if(j != cnt - 1) { cout<<"->"<<result[j]; } else { cout<<result[j]; } } cout<<endl; } }}void Graph_Link::AllLength() { int edge[num_v][num_v]; int floyd[num_v][num_v]; for(int i = 0; i < num_v; ++ i) { for(int j = 0; j < num_v; ++ j) { if(i == j) { edge[i][j] = 0; } else { edge[i][j] = MAX_W; } } } Edge *p = NULL; for(int i = 0; i < num_v; ++ i) { p = Head[i].head1; while(p != NULL) { edge[i][p->VerAdj] = p->weight; p = p->next; } } int path[num_v][num_v]; for(int i = 0; i < num_v; ++ i) { for(int j = 0; j < num_v; ++ j) { floyd[i][j] = edge[i][j]; if(i != j && floyd[i][j] < MAX_W) { path[i][j] = i; } else { path[i][j] = -1; } } } for(int k = 0; k < num_v; ++ k) { for(int i = 0; i < num_v; ++ i) { if(i != k) { for(int j = 0; j < num_v; ++ j) { if(j != k && j != i && floyd[i][k] < MAX_W && floyd[k][j] < MAX_W) { if(floyd[i][k] + floyd[k][j] < floyd[i][j]) { floyd[i][j] = floyd[i][k] + floyd[k][j]; path[i][j] = path[k][j]; } } } } } } for(int i = 0; i < num_v; ++ i) { for(int j = 0; j < num_v; ++ j) { if(i == j) { continue; } if(floyd[i][j] < MAX_W ) { cout<<"从点"<<i<<"到点"<<j<<"加权最短路径长度为:"<<floyd[i][j]<<endl; cout<<"最短路径为:"; int result[num_v]; memset(result, 0, sizeof(result)); int cnt = 0; result[cnt] = j; while(path[i][result[cnt]] != i) { cnt ++ ; result[cnt] = path[i][result[cnt - 1]]; } cnt ++ ; result[cnt] = i; for(int k = cnt; k > 0; -- k) { cout<<result[k]<<"->"; } cout<<result[0]<<endl; } else { cout<<"从点"<<i<<"到点"<<j<<"不存在路径"<<endl; } } }}void Graph_Link::Prim(int u0) { int sumweight = 0; int lowcost[num_v]; int nearvex[num_v]; Edge *p = Head[u0].head1; for(int i = 0; i < num_v; ++ i) { lowcost[i] = MAX_W; nearvex[i] = u0; } while(p != NULL) { lowcost[p->VerAdj] = p->weight; p = p->next; } nearvex[u0] = -1; for(int i = 0; i < num_v; ++ i) { int min = MAX_W; int v = -1; for(int j = 0; j < num_v; ++ j) { if(nearvex[j] != -1 && lowcost[j] < min) { min = lowcost[j]; v = j; } } if(v != -1) { printf("%d -> %d 这条边被选中,其权值是 %d\n", nearvex[v], v, lowcost[v]); nearvex[v] = -1; sumweight += lowcost[v]; p = Head[v].head1; while(p != NULL) { if(nearvex[p->VerAdj] != -1 && p->weight < lowcost[p->VerAdj]) { lowcost[p->VerAdj] = p->weight; nearvex[p->VerAdj] = v; } p = p->next; } } } printf("最小生成树的总权值为:%d\n", sumweight);}
#include<cstdio>#include<iostream>#include<algorithm>#include<stack>#include<cstring>#include<string>#include"Graph.h"#include<queue>using namespace std;int main(){ printf("请选择图的存储方式 0。邻接矩阵存储 1 邻接链表存储\n"); int store; Graph *graph; scanf("%d", &store); FILE *fp = fopen("graph.txt", "r"); if(store == 0) { graph = new Graph_Matrix(fp); } else { graph = new Graph_Link(fp); } fclose(fp); printf("请选择你要执行的操作\n0.退出\n1.向图中加入一条边\n2.从图中删除一条边\n3.图的深度优先遍历(递归)\n4.图的深度优先遍历(迭代)\n"); printf("5.图的宽度优先遍历\n6.图的拓扑排序\n7.输出图的关键路径\n8.求无权图中顶点v到其他顶点的最短路径\n"); printf("9.求正权图中顶点v到其他顶点的最短路径\n10.求正权图中每对顶点间的最短路径\n11.构造图的最小支撑树的普里姆算法\n"); int choose; scanf("%d", &choose); int u, v, w; while(choose) { switch(choose) { case 1: printf("请输入所要插入边的两个顶点以及边的权值\n"); scanf("%d %d %d", &u, &v, &w); graph->InsertEdge(u, v, w); break; case 2: printf("请输入所要删除边的两个顶点\n"); scanf("%d %d", &u, &v); graph->DeleteEdge(u, v); break; case 3: graph->DepthFirstSearch(); break; case 4: printf("请输入深度优先遍历(迭代)的起点"); scanf("%d", &u); graph->DFS(u); break; case 5: printf("请输入宽度优先遍历的起点"); scanf("%d", &u); graph->BFS(u); break; case 6: graph->TopoOrder(); break; case 7: graph->CriticalPath(); break; case 8: printf("请输入顶点v"); scanf("%d", &v); graph->ShortestPath(v); break; case 9: printf("请输入顶点v"); scanf("%d", &v); graph->DShortestPath(v); break; case 10: graph->AllLength(); break; case 11: printf("请输入prim创建最小支撑树的起点"); scanf("%d", &u); graph->Prim(u); } printf("请选择你要执行的操作\n0.退出\n1.向图中加入一条边\n2.从图中删除一条边\n3.图的深度优先遍历(递归)\n4.图的深度优先遍历(迭代)\n"); printf("5.图的宽度优先遍历\n6.图的拓扑排序\n7.输出图的关键路径\n8.求无权图中顶点v到其他顶点的最短路径\n"); printf("9.求正权图中顶点v到其他顶点的最短路径\n10.求正权图中每对顶点间的最短路径\n11.构造图的最小支撑树的普里姆算法\n"); scanf("%d", &choose); }}
0 0
- 程序设计代码 贴着玩。。七
- 程序设计代码,贴着玩。。一
- 程序设计代码。。贴着玩 二
- 程序设计代码 贴着玩。。 三
- 程序设计代码 贴着玩。。 四
- 程序设计代码 贴着玩 。。 五
- 程序设计代码 贴着玩。。六
- 程序设计代码 贴着玩。。八
- Windows Socket 代码贴着防忘
- 编译原理程序设计实践(七)解释器的相关代码
- 七、t_sql程序设计基础
- 程序设计七误区
- 通用程序设计(七)
- PHP程序设计读书笔记七
- javascript 高级程序设计 七
- 好想也写一点技术文章贴着~
- 学会玩代码
- 80386ASM程序设计基础(七)
- Linux下几种文件传输命令
- 行人检测(Pedestrian Detection)资源
- d7下 TDrawingStyle TImageType DecimalSeparator
- 经典的机器学习方面源代码库
- iOS闪光灯操作
- 程序设计代码 贴着玩。。七
- 合并exe dll
- xStream完美转换XML、JSON
- 【转载】图解linux下top命令的使用
- [Effective C++] 函数名覆盖
- 深入剖析阿里巴巴云梯YARN集群
- java笔记3
- java经典算法排序
- 从数据到价值——创业团队应该关注的四个阶段