算法-图论-有权图
稠密图
#ifndef DENSEGRAPH_H #define DENSEGRAPH_H #include <iostream> #include <vector> #include <cassert> #include "Edge.h" using namespace std; //稠密图 -- 邻接矩阵 --有权 template <typename Weight> class DenseGraph{ private: int n,m;//点数和边数 bool directed;//有向图还是无向图 vector<vector<Edge<Weight>* >> g;//邻接矩阵,两个向量嵌套 public: DenseGraph(int n,bool directed){ this->n = n; this->m = 0; this->directed = directed; for(int i=0;i<n;i++) g.push_back(vector<Edge<Weight>* >(n,NULL));//创建矩阵 } ~DenseGraph(){ for(int i=0;i<n;i++) for(int j=0;j<n;j++) if(g[i][j] != NULL) delete g[i][j]; } int V(){return n;}//顶点 int E(){return m;}//边 void addEdge(int v,int w,Weight weight){ assert(v>=0 && v<n); assert(w>=0 && w<n); if (hasEdge(v,w)){ delete g[v][w]; if(!directed) delete g[w][v]; m --; } g[v][w] = new Edge<Weight>(v,w,weight); if(!directed) g[w][v] = new Edge<Weight>(v,w,weight); m ++; } bool hasEdge(int v,int w){ assert(v>=0 && v<n); assert(w>=0 && w<n); return g[v][w] != NULL; } void show(){ for(int i=0;i<n;i++){ for(int j=0;j<n;j++) if(g[i][j]) cout<<g[i][j]->wt() <<"\t"; else count<<"NULL\t"; cout<<endl; } } class adjIterator{ private: DenseGraph &G; int v; int index; public: adjIterator(DenseGraph &graph,int v):G(graph){ this->v = v; this->index=-1; } Edge<Weight>* begin(){ index = -1; return next(); } Edge<Weight>* next(){ for(index +=1;index <= G.V(); index++) if(G.g[v][index]) return G.g[v][index]; return NULL; } bool end(){ return index >= G.V(); } }; }; #endif
稀疏图
#ifndef SPARSEGRAPH_H #define SPARSEGRAPH_H #include <iostream> #include <vector> #include <cassert> #include "Edge.h" using namespace std; //稀疏图图 -- 邻接表 --有权 template<typename Weight> class SparseGraph{ private: int n,m;//点数和边数 bool directed;//有向图还是无向图 vector<vector<Edge<Weight> *>> g; public: SparseGraph(int n,bool directed){ this->n = n; this->m = 0; this->directed = directed; for(int i=0;i<n;i++) g.push_back(vector<Edge<Weight> *>()); } ~SparseGraph(){ for(int i=0;i<n;i++) for(int j=0;j<g[i].size();j++) delete g[i][j]; }; int V(){return n;}//顶点 int E(){return m;}//边 void addEdge(int v,int w,Weight weight){ assert(v>=0 && v<n); assert(w>=0 && w<n); g[v].push_back(new Edge(v,w,weight)); if(v != w && !directed)//处理自环边 g[w].push_back(new Edge<Weight>(w,v,weight)); m++; } bool hasEdge(int v,int w){ assert(v>=0 && v<n); assert(w>=0 && w<n); for(int i=0;i<g[v].size();i++){ if(g[v][i]->other(v) == w) return true; } return false; } void show(){ for(int i=0;i<n;i++){ cout<<"vertex "<<i <<":\t"; for(int j=0;j<g[i].size();j++) cout<<"( to:"<<g[i][j]->w()<<",wt:"<<g[i][j]->wt()<<")\t"; cout<<endl; } } //迭代器,迭代顶点的相邻的边 class adjIterator{ private: SparseGraph &G; int v; int index; public: adjIterator(SparseGraph &graph,int v):G(graph){ this->v = v; this->index=0; } Edge<Weight>* begin(){ index =0; if(G.g[v].size()) return G.g[v][index]; return NULL; } Edge<Weight>* next(){ index ++; if(index <G.g[v].size()) return G.g[v][index]; return NULL; } bool end(){ return index>= G.g[v].size(); } }; }; #endif
Edge.h
#include <iostream> #include <cassert> using namespace std; template<typename Weight> class Edge{ private: int a,b; //两个顶点 Weight weight;//权值 public: Edge(int a,int b,Weight weight){ this->a =a; this->b = b; this->weight =weight; } Edge(){} ~Edge(){} int v(){return a;}//获取顶点a int w(){return b;}//获取顶点b Weight wt(){return weight;}//获取权重 int other(int x){ assert(x==a || x == b); return x == a ? b : a; //返回已知顶点的另一端 } friend ostream& operator<<(ostream &os,const Edge &e){ os<<e.a<<"-"<<e.b<<": "<<e.weight; return os; } bool operator<(Edge<Weight>& e){ return weight < e.wt(); } bool operator<=(Edge<Weight>& e){ return weight <= e.wt(); } bool operator>(Edge<Weight>& e){ return weight > e.wt(); } bool operator>=(Edge<Weight>& e){ return weight >= e.wt(); } bool operator==(Edge<Weight>& e){ return weight == e.wt(); } };
ReadGraph
#ifndef READGRAPH_H #define READGRAPH_H #include <iostream> #include <string> #include <fstream> #include <sstream> #include <vector> #include <cassert> using namespace std; template <typename Graph,typename Weight> class ReadGraph{ public: ReadGraph(Graph &graph,const string &filename){ ifstream file(filename); string line; int V,E; assert(file.is_open()); assert(getline(file,line)) stringstream ss(line); ss>>V>>E; assert(V ==graph.V()); for(int i =0;i<E;i++){ assert(getline(file,line)) stringstream ss(line); int a,b; Weight w; ss>>a>>b>>w; assert(a >= 0 && a<V); assert(b >= 0 && b<V); graph.addEdge(a,b,w); } } }; #endif