找工作时当练习写的,仅供参考。
头文件:
#ifndef GRAPH_H_INCLUDED
#define GRAPH_H_INCLUDED
#define Max 10000
//adjacent matrix
class MGraph{
private:
int TotVer;
vector<int> Vertics;
vector<vector<int> > Edge;
public:
MGraph(){ }
MGraph(int t):TotVer(t){
//read vertics
cout<<"read vertics"<<endl;
int v;
for(int i=0;i<t;++i){
cin>>v;
Vertics.push_back(v);
}
//read edges
cout<<"read edges"<<endl;
Edge.resize(t);
for(int i=0;i<t;++i)
Edge[i].resize(t,0);
for(int i=0;i<t;++i)
for(int j=0;j<t;++j)
if(i!=j) Edge[i][j]=Max;
int i,j,cur;
while(cin>>i>>j>>cur){
if(i==-1&&j==-1&&cur==-1) break;
if(i!=j) Edge[i][j]=Edge[j][i]=cur;
}
}
int GetTotVec(){
return TotVer;
}
vector<int>& GetVertics(){
return Vertics;
}
vector<vector<int> >& GetEdge(){
return Edge;
}
void Dijkstra(int);
void Floyd();
};
//adjacent table
struct Edge{
int dest;
int cost;
Edge* next;
Edge(int d,int c):dest(d),cost(c),next(NULL){ }
};
struct Vertex{
int data;
Edge* adj;
Vertex():data(0),adj(NULL){ }
};
struct MSTNode{
int tail,head;
int cost;
};
class AGraph{
private:
int TotVer;
int TotEdge;
vector<Vertex> NodeTable;
public:
AGraph(){ }
AGraph(int t,int e):TotVer(t),TotEdge(e){
int d;
int tail,head,cost;
Edge* cure;
//read vertics
cout<<"read vertics"<<endl;
NodeTable.resize(t);
for(int i=0;i<t;++i){
cin>>d;
NodeTable[i].data=d;
}
//read edges
cout<<"read edges"<<endl;
for(int i=0;i<e;++i){
cin>>tail>>head>>cost;
int k=0;
while(k!=tail) ++k;
cure=NodeTable[k].adj;
if(cure==NULL) NodeTable[k].adj=new Edge(head,cost);
else{
while(cure->next!=NULL) cure=cure->next;
cure->next=new Edge(head,cost);
}
/*k=0;
while(k!=head) ++k;
cure=NodeTable[k].adj;
if(cure==NULL) NodeTable[k].adj=new Edge(tail,cost);
else{
while(cure->next!=NULL) cure=cure->next;
cure->next=new Edge(tail,cost);
}*/
}
}
~AGraph(){
Edge *p;
for(int i=0;i<TotVer;++i){
p=NodeTable[i].adj;
while(p!=NULL){
NodeTable[i].adj=p->next;
delete p;
p=NodeTable[i].adj;
}
}
}
vector<Vertex>& GetNode(){
return NodeTable;
}
void DFS(int v,vector<int>& flag);
void DFS();
void BFS(int v,vector<int>& flag);
void BFS();
void Kruskal();
int find_set(vector<vector<int> >& v,int k);
int union_set(vector<vector<int> >&v,int i,int j);
void Prim();
vector<int> TopologicalSort();
void CriticalPath();
};//end
#endif // GRAPH_H_INCLUDED
各种图算法:
#include <iostream>
#include <vector>
#include <deque>
#include <iterator>
#include <cstdlib>
using namespace std;
#include <graph.h>
//dfs
void AGraph::DFS(int v,vector<int>& flag){
cout<<NodeTable[v].data<<endl;
flag[v]=1;
int w;
Edge* p=NodeTable[v].adj;
while(p!=NULL){
w=p->dest;
if(!flag[w]) DFS(w,flag);
p=p->next;
}
}
void AGraph::DFS(){
vector<int> flag(TotVer,0);
for(int i=0;i<TotVer;++i)
if(!flag[i]) DFS(i,flag);
}
//bfs
void AGraph::BFS(int v,vector<int>& flag){
deque<int> d;
int w;
Edge* p;
cout<<NodeTable[v].data<<endl;
flag[v]=1;
d.push_back(v);
while(!d.empty()){
v=d.front();
d.pop_front();
p=NodeTable[v].adj;
while(p!=NULL){
w=p->dest;
if(!flag[w]){
cout<<NodeTable[w].data<<endl;
flag[w]=1;
d.push_back(w);
}
p=p->next;
}
}
}//end bfs
void AGraph::BFS(){
vector<int> flag(TotVer,0);
for(int i=0;i<TotVer;++i)
if(!flag[i]) BFS(i,flag);
}
//kruskal
int AGraph::find_set(vector<vector<int> >& v,int k){ //寻找点所在连通分量
for(int i=0;i<v.size();++i)
if(v[i][k]) return i;
}
int AGraph::union_set(vector<vector<int> >&v,int i,int j){ //合并连通分量
for(int k=0;k<TotVer;++k)
if(v[i][k]||v[j][k]) v[i][k]=1;
v.erase(v.begin()+j);
}
void AGraph::Kruskal(){
vector<vector<int> > ver(TotVer,vector<int>(TotVer,0));//存放连通分量
vector<MSTNode> vedge;//存放各边
vector<MSTNode> mst;//存放最小生成树
vector<int> flag(TotVer,0);
Edge* p;
MSTNode tmp;
for(int i=0;i<TotVer;++i)
ver[i][i]=1;
for(int i=0;i<TotVer;++i){
if(!flag[i]) flag[i]=1;
p=NodeTable[i].adj;
while(p!=NULL){
tmp.tail=i;
tmp.head=p->dest;
tmp.cost=p->cost;
if(!flag[tmp.head]) vedge.push_back(tmp);
p=p->next;
}
}
//sort vedge
for(int i=1;i<vedge.size();++i){
MSTNode tmpnode=vedge[i];
int tmp=vedge[i].cost;
int Left=0,Right=i-1;
while(Left<=Right){
int mid=(Left+Right)/2;
if(tmp<vedge[mid].cost) Right=mid-1;
else Left=mid+1;
}
for(int j=i-1;j>=Left;--j)
vedge[j+1]=vedge[j];
vedge[Left]=tmpnode;
}
for(int i=0;i<TotEdge;++i){ //kruskal
int v=find_set(ver,vedge[i].tail);
int w=find_set(ver,vedge[i].head);
if(v!=w){
mst.push_back(vedge[i]);
union_set(ver,v,w);
}
}
for(int i=0;i<mst.size();++i)
cout<<mst[i].tail<<" "<<mst[i].head<<" "<<mst[i].cost<<endl;
}
//prim
void AGraph::Prim(){
vector<int> minTree;//最小树的节点
vector<MSTNode> mst;
vector<int> flag(TotVer,0);//进树标志
MSTNode mnode;
minTree.push_back(0);//某个节点进树,在这里选择0节点
flag[0]=1;
for(int i=1;i<TotVer;++i){//建树
int msttail=-1;
int msthead=-1;
int tmp=Max;
Edge* p;
for(int j=0;j<minTree.size();++j){ //寻找树内节点到树外各个节点的有最短距离的边
int tail=minTree[j];
int head;
p=NodeTable[tail].adj;
while(p!=NULL){
head=p->dest;
if(!flag[head]&&p->cost<tmp){
tmp=p->cost;
msthead=head;
msttail=tail;
}
p=p->next;
}
}
minTree.push_back(msthead);
flag[msthead]=1;
mnode.tail=msttail;
mnode.head=msthead;
mnode.cost=tmp;
mst.push_back(mnode);//加入最小生成树
}
for(int i=0;i<mst.size();++i)
cout<<mst[i].tail<<" "<<mst[i].head<<" "<<mst[i].cost<<endl;
}//end prim
//dijkstra
void MGraph::Dijkstra(int v){
vector<int> dist(TotVer);//当前状态下v距离未进入的节点的最短距离
vector<int> path(TotVer,-1);//当前最短路径状态下各个节点的前驱节点
vector<int> flag(TotVer,0);//节点进入标志
flag[v]=1;
for(int i=0;i<TotVer;++i){
dist[i]=Edge[v][i];
if(i!=v&&dist[i]<Max) path[i]=v;
}
for(int i=0;i<TotVer-1;++i){
int min=Max;
int u;
for(int j=0;j<TotVer;++j)//寻找下一个节点
if(!flag[j]&&dist[j]<min){
u=j;
min=dist[j];
}
flag[u]=1;
for(int j=0;j<TotVer;++j)//更新dist和path
if(!flag[j]&&dist[u]+Edge[u][j]<dist[j]){
dist[j]=dist[u]+Edge[u][j];
path[j]=u;
}
}
for(int i=0;i<TotVer;++i){
int w=i;
cout<<w;
while(path[w]!=-1){
cout<<"<--"<<path[w];
w=path[w];
}
cout<<endl;
}
}
//floyd
void MGraph::Floyd(){
vector<vector<int> > dist(TotVer,vector<int>(TotVer));
vector<vector<int> > path(TotVer,vector<int>(TotVer,-1));
for(int i=0;i<TotVer;++i)
for(int j=0;j<TotVer;++j){
dist[i][j]=Edge[i][j];
if(i!=j&&dist[i][j]<Max) path[i][j]=i;
}
for(int k=0;k<TotVer;++k)
for(int i=0;i<TotVer;++i)
for(int j=0;j<TotVer;++j)
if(dist[i][k]+dist[k][j]<dist[i][j]){
dist[i][j]=dist[i][k]+dist[k][j];
path[i][j]=path[k][j];
}
for(int i=0;i<TotVer;++i){
cout<<i<<":"<<endl;
for(int j=0;j<TotVer;++j){
int k=j;
cout<<"<"<<i<<","<<j<<">:";
cout<<j;
k=path[i][j];
while(k!=-1){
cout<<"<--"<<k;
k=path[i][k];
}
cout<<endl;
}
cout<<"-------------------"<<endl;
}
}//end floyd
//TopologicalSort
vector<int> AGraph::TopologicalSort(){
vector<int> count(TotVer,0);
vector<int> verset;
int top=-1;
for(int i=0;i<TotVer;++i){//Initialize the count
Edge* p=NodeTable[i].adj;
while(p){
++count[p->dest];
p=p->next;
}
}
for(int i=0;i<TotVer;++i)//initialze the stack
if(count[i]==0){
count[i]=top;
top=i;
}
for(int i=0;i<TotVer;++i){ //sort
if(top==-1){
cout<<"has a cycle"<<endl;
exit(0);
}
else{
int j=top;
top=count[top];
verset.push_back(j);
Edge* p=NodeTable[j].adj;
while(p){
if(--count[p->dest]==0){
count[p->dest]=top;
top=p->dest;
}
p=p->next;
}
}
}
return verset;
}//end tsort
//critical path
void AGraph::CriticalPath(){
vector<int> tsort;
vector<int> ve(TotVer,0);
vector<int> vl(TotVer,0);
Edge* p=NULL;
int k,e,l;
tsort=TopologicalSort();
for(int i=0;i<TotVer;++i){
int t=tsort[i];
p=NodeTable[t].adj;
while(p){
k=p->dest;
if(ve[t]+p->cost>ve[k]) ve[k]=ve[t]+p->cost;
p=p->next;
}
}
for(int i=0;i<TotVer;++i) vl[i]=ve[TotVer-1];
for(int i=TotVer-2;i>=0;--i){
int t=tsort[i];
p=NodeTable[t].adj;
while(p){
k=p->dest;
if(vl[k]-p->cost<vl[t]) vl[t]=vl[k]-p->cost;
p=p->next;
}
}
for(int i=0;i<TotVer;++i){ //critical path
p=NodeTable[i].adj;
while(p){
k=p->dest;
e=ve[i];
l=vl[k]-p->cost;
if(l==e) cout<<"<"<<i<<","<<k<<">"<<"is critical path"<<endl;
p=p->next;
}
}
}//critical path