#include <iostream> #include <algorithm> #include <vector> #include <iomanip> using namespace std;
//引以为荣的程序.还有几个小部分改,以待完美. const int N=7,MAX=1000;
class PrimTree{ int map[N][N]; bool beVisited[N]; bool beExist[N]; int count; int Pass[N]; public: PrimTree(int table[][N]);//构建 Prim树 int Go(int startnode,int endnode,int *& info,int & len);//从结点startnode到endnode,返回最短路径及详细信息 int DFS(int v,int endonde);//从第v个顶点出发深度遍历map };
PrimTree::PrimTree(int table[][N]) { bool beInclude[N]={false}; int lowcost[N]={0}; int startnode[N]={0}; for (int i=2;i<=N;i++) { lowcost[i]=table[1][i]; //lowcost初始化为从第一个结点到各个节点的距离 startnode[i]=1; //起始结点 } startnode[1]=1; beInclude[1]=true; //结节1被包含进入目标图中 for (int m=0;m<N-1;m++) { int temp=MAX,armRow=0; for (int x=2;x<=N;x++) { if (lowcost[x]<temp && !beInclude[x]) { temp=lowcost[x]; armRow=x; } } beInclude[armRow]=true; //更新划入范围的结点到其它结点的最短距离 for(int y=1;y<=N;y++) { if (table[armRow][y]<lowcost[y] && !beInclude[y]) { lowcost[y]=table[armRow][y]; startnode[y]=armRow; } } } /**//* for test. copy(lowcost+1,lowcost+N,ostream_iterator<int>(cout," ")); cout<<endl; copy(startnode+1,startnode+N,ostream_iterator<int>(cout," ")); cout<<endl; */ //建立Prim树的矩阵图. { for (int i=0;i<N;i++) { for (int j=0;j<N;j++) { map[i][j]=0; } } } { for (int i=2;i<N;i++) { map[startnode[i]][i]=lowcost[i]; map[i][startnode[i]]=lowcost[i]; } } }
int PrimTree::Go(int startnode,int endnode,int * &info,int &len) { //出始化成员变量 for (int i=1;i<=N-1;i++) { beExist[i]=true; beVisited[i]=false; Pass[i]=0; } count=0; DFS(startnode,endnode);
/**//* for test. copy(beVisited+1,beVisited+N,ostream_iterator<bool>(cout," ")); cout<<endl; copy(beExist+1,beExist+N,ostream_iterator<bool>(cout," ")); cout<<endl; copy(Pass,Pass+N,ostream_iterator<int>(cout," ")); cout<<endl; */ //找出从起始到终止结点间的途径节点 vector<int> col; { for (int i=0;i<N;i++) { if (Pass[i] && beExist[Pass[i]]) { col.push_back(Pass[i]); //cout<<Pass[i]<<"->"; } } }
info=new int[col.size()]; copy(col.begin(),col.end(),info); len=col.size(); /**//* for test copy(info,info+col.size(),ostream_iterator<int>(cout," ")); cout<<endl; */
int lou=0; //计算起点到终点的具体长度. { int b=0,n=1; for (int i=0;i<col.size()-1;i++) { lou+=map[info[b]][info[n]]; b=n; n++; } //cout<<lou<<endl; } return lou; }
// It works! Great! 终于写好了这个最短路径的算法, // 先遍历图,再标出旁路的节点..great!!!! zhangyuntao 3.31 原创经典. int PrimTree::DFS(int v,int endonde) { Pass[count++]=v; beVisited[v]=true; if(v==endonde) return 1; int m=0; for (int i=1;i<=N-1;i++) { if (map[v][i] && !beVisited[i]) { m+=DFS(i,endonde); } }
if (m==0) { beExist[v]=false; //歧路标志设为0; return 0; } return 1; } //Great!
void main() { int table[N][N]={ {MAX,MAX,MAX,MAX,MAX,MAX,MAX}, {MAX,MAX,6, 1, 5, MAX,MAX}, {MAX,6, MAX,5, MAX,3, MAX}, {MAX,1, 5, MAX,5, 6, 4}, {MAX,5, MAX,5, MAX,MAX,2}, {MAX,MAX,3, 6, MAX,MAX,1}, {MAX,MAX,MAX,4, 2, 1, MAX}, }; { for (int i=1;i<N;i++) { for (int j=1;j<N;j++) { cout<<setw(5)<<(table[i][j]== MAX ? -1 : table[i][j]); } cout<<endl; } } cout<<"--------------------------------------------------"<<endl; PrimTree p(table); int start,end; cout<<"输入起始节点与终止节点(1到6)"<<endl; int *info ,len; while(cin>>start>>end) { if (start<=6 && end<=6) { cout<<"最短路径为 "<<p.Go(start,end,info,len)<<endl; copy(info,info+len-1,ostream_iterator<int>(cout,"->")); cout<<info[len-1]<<endl; delete []info; } cout<<"输入起始节点与终止节点"<<endl; } system("pause") ; }
|