简单实现dijstra算法和floyd算法并打印所有最短路径
2014-09-12 18:05
316 查看
没写析构函数
#include<iostream> #include<stack> #include<string> #include<assert.h> #include<fstream> #include<vector> #include<set> using namespace std; typedef struct Edge{ int pos;//该边终点的下标 int weight; Edge* next; Edge(int p,int w):pos(p),weight(w),next(NULL){} }Edge; typedef struct GraphNode{ string name; Edge* first; GraphNode(const string& s=""):name(s),first(NULL){} }GraphNode; class Graph{ private: GraphNode* nodes; int nodes_cnt; void getShorestPath(int f,int t,vector<set<int> >&parent,vector<vector<string> >&ans,vector<string>& tmp){ if(f==t){ tmp.push_back(nodes[f].name); ans.push_back(tmp); tmp.pop_back(); return; } tmp.push_back(nodes[t].name); for(set<int>::iterator p=parent[t].begin();p!=parent[t].end();++p){ getShorestPath(f,*p,parent,ans,tmp); } tmp.pop_back(); } void getShorestPath(int f,int t,vector<vector<set<int> > >&next,vector<vector<string> >&ans,vector<string>& tmp){ if(f==t){ tmp.push_back(nodes[t].name); ans.push_back(tmp); tmp.pop_back(); return; } tmp.push_back(nodes[f].name); for(set<int>::iterator p=next[f][t].begin();p!=next[f][t].end();++p){ getShorestPath(*p,t,next,ans,tmp); } tmp.pop_back(); } void printPath(const vector<vector<string> >&ans){ for(int i=0;i<ans.size();++i){ cout<<"\tpath"<<i+1<<": "; for(int j=0;j<ans[i].size();++j) cout<<ans[i][j]<<" "; cout<<endl; } } public: Graph(const vector<string>& nds):nodes(new GraphNode[nds.size()]),nodes_cnt(nds.size()){ for(int i=0;i<nodes_cnt;++i) nodes[i]=nds[i]; } void insertEdge(int f,int t,int w){ assert(f>=0&&f<nodes_cnt&&t>=0&&t<nodes_cnt); Edge* edge=new Edge(t,w); edge->next=nodes[f].first; nodes[f].first=edge; edge=new Edge(f,w); edge->next=nodes[t].first; nodes[t].first=edge; } void shortestPath(int f,int t){ assert(f>=0&&f<nodes_cnt&&t>=0&&t<nodes_cnt); vector<bool> visited; visited.resize(nodes_cnt); memset(&visited[0],false,nodes_cnt); vector<set<int> > parent; parent.resize(nodes_cnt); vector<int> dis; dis.resize(nodes_cnt); const int MAX_INT=0x7fffffff; for(int i=0;i<nodes_cnt;++i) dis[i]=MAX_INT; for(Edge* p=nodes[f].first;p!=NULL;p=p->next){ dis[p->pos]=p->weight; parent[p->pos].insert(f); } dis[f]=0; parent[f].insert(f); bool found=false; for(int i=0;i<nodes_cnt;++i){ int min_pos=-1; for(int j=0;j<nodes_cnt;++j){ if(visited[j]==false){ if(min_pos==-1||dis[min_pos]>dis[j]) min_pos=j; } } if(min_pos==t&&dis[min_pos]!=INT_MAX) found=true; if(!found&&dis[min_pos]==INT_MAX)break; visited[min_pos]=true; for(Edge* p=nodes[min_pos].first;p!=NULL;p=p->next){ if(visited[p->pos]==false){ if(dis[p->pos]>dis[min_pos]+p->weight){ dis[p->pos]=dis[min_pos]+p->weight; parent[p->pos].clear(); parent[p->pos].insert(min_pos); }else if(dis[p->pos]==dis[min_pos]+p->weight){ parent[p->pos].insert(min_pos); } } } } if(!found){ cout<<nodes[f].name<<" to "<<nodes[t].name<<" does not connect"<<endl; return; } vector<vector<string> >ans; vector<string> tmp; getShorestPath(f,t,parent,ans,tmp); for(int i=0;i<ans.size();++i){ for(int j=0;j<ans[i].size()/2;++j) swap(ans[i][j],ans[i][ans[i].size()-1-j]); } cout<<"Shortest Path from "<<nodes[f].name<<" to "<<nodes[t].name<<" Distance="<<dis[t]<<endl; printPath(ans); } void Floyd(){ vector<vector<set<int> > >next; next.resize(nodes_cnt); for(int i=0;i<nodes_cnt;++i) next[i].resize(nodes_cnt); for(int i=0;i<nodes_cnt;++i){ for(Edge* p=nodes[i].first;p!=NULL;p=p->next) next[i][p->pos].insert(p->pos); } vector<vector<int> >dis; dis.resize(nodes_cnt); const int MAX_INT=0x7fffffff; for(int i=0;i<nodes_cnt;++i){ dis[i].resize(nodes_cnt); for(int j=0;j<nodes_cnt;++j) dis[i][j]=MAX_INT; } for(int i=0;i<nodes_cnt;++i){ for(Edge* p=nodes[i].first;p!=NULL;p=p->next) dis[i][p->pos]=p->weight; } for(int i=0;i<nodes_cnt;++i) dis[i][i]=0; for(int i=0;i<nodes_cnt;++i){ for(int j=0;j<nodes_cnt;++j){ for(int k=0;k<nodes_cnt;++k){ if(dis[j][i]!=INT_MAX&&dis[i][k]!=INT_MAX){ if(dis[j][k]>dis[j][i]+dis[i][k]){ dis[j][k]=dis[j][i]+dis[i][k]; next[j][k].clear(); next[j][k]=next[j][i]; }else if(dis[j][k]==dis[j][i]+dis[i][k]){ for(set<int>::iterator p=next[j][i].begin();p!=next[j][i].end();++p) next[j][k].insert(*p); } } } } } for(int i=0;i<nodes_cnt;++i){ for(int j=0;j<nodes_cnt;++j){ if(dis[i][j]==INT_MAX){ cout<<nodes[i].name<<" "<<nodes[j].name<<" does not connect"<<endl; continue; } cout<<"Shorest path from "<<nodes[i].name<<" to "<<nodes[j].name<<"Distance = "<<dis[i][j]<<endl; vector<vector<string> >ans; vector<string> tmp; getShorestPath(i,j,next,ans,tmp); printPath(ans); } } } }; int main(void){ vector<string> v; v.resize(10); for(int i=0;i<10;++i) v[i]='0'+i; Graph graph(v); graph.insertEdge(0,1,1); graph.insertEdge(0,2,3); graph.insertEdge(0,7,1); graph.insertEdge(1,3,1); graph.insertEdge(1,6,2); graph.insertEdge(2,3,1); graph.insertEdge(2,7,2); //graph.insertEdge(3,4,2); graph.insertEdge(3,5,2); graph.insertEdge(3,9,4); graph.insertEdge(5,7,4); graph.insertEdge(5,8,1); graph.insertEdge(5,9,2); graph.insertEdge(8,9,1); for(int i=0;i<10;++i) for(int j=0;j<10;++j) graph.shortestPath(i,j); cout<<"<------------------------>"<<endl; graph.Floyd(); return 0; }
相关文章推荐
- 最短路径简单实现(Dijkastra算法和Floyd算法)
- 所有顶点间最短路径FloydWarshall算法实现文件C++
- 图两点间的最短路径,所有路径算法C语言实现
- 利用Dijkstra算法实现记录每个结点的所有最短路径
- 算法导论第二十五章-所有结点对的最短路径问题-Cpp代码实现
- 最短路径算法设计与实现(Dijkstra算法和Floyd算法)
- 有向图最短路径floyd算法的python实现
- 最短路径Dijkstra算法实现和Floyd算法实现
- Floyd算法(所有点对最短路径)
- 打印无权无向图的所有最短路径
- 实现迷宫问题的所有路径及最短路径程序
- 最短路径:Dijkstra,Bellman,SPFA,Floyd算法的实现
- Floyd算法-所有顶点之间的最短路径(C++模板)
- Floyd算法求最短路径,JAVA实现
- HDOJ 2544 最短路(最短路径 dijkstra算法,SPFA邻接表实现,floyd算法)
- Floyd算法求所有点对之间的最短路径
- MPI实现有向图所有点间最短路径
- 图论最短路径算法-Floyd算法-JAVA代码实现
- 华为OJ 逛动物园-不打印路径只是简单输出最短路径的值
- 利用Dijkstra算法实现记录每个结点的所有最短路径