程序设计代码 贴着玩。。七

来源:互联网 发布:百度电影推荐系统算法 编辑:程序博客网 时间: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
原创粉丝点击