#include<iostream>
#include <iomanip>
#include <stack>
#include <deque>
#include <fstream>
using namespace std;
struct primnode
{
public:
char begvex;
char endvex;
int lowcost;
};
struct adknode
{
int dist;//最近距离
char way[50];//顶点数组
int nodenum;//经过的顶点数
};
class Mgraph//邻接矩阵储存结构
{
public:
Mgraph(){}
~Mgraph(){}
void CreatMGraph();
void DFS (int );//用递归实现
void DFS1(int );//非递归
void BFS(int );
void print();
void prim();
int mini();
int low();//最短距离函数的辅助函数
int LocateVex(char);
void kruskal();
void Dijkstra();
void Floyd();
private:
int number;//顶点数目
int arcnum;//边的数目
char vexs[50];
int arcs[50][50];
int visited[50];//便利时的辅助工具
primnode closeedge[50];//prim
adknode dist[50];//最短路径
int D[20][20];//floyd算法距离
int P[20][20][20];//floyd算法路径
};
int Mgraph::LocateVex(char s)
{
for(int i=0;i<number;i++)
if (vexs[i]==s)
return i;
return -1;
}
void Mgraph::print()
{
cout<<"顶点为: ";
for(int k=0;k<number;k++)
cout<<vexs[k];
cout<<endl;
for(int i=0;i<number;i++)
{
for(int j=0;j<number;j++)
cout<<setw(6)<<left<<arcs[i][j]<<" ";
cout<<endl;
}
for(int m=0;m<number;m++)
cout<<visited[m];
cout<<endl;
}
void Mgraph::CreatMGraph()//图的邻接矩阵储存结构
{
char vex1,vex2;
int i,j,k,m;
cout<<"请输入定点数,边数:"<<endl;
cin>>number>>arcnum;
cout<<"请输入顶点(字符串类型):"<<endl;
for(i=0;i<number;i++)
cin>>vexs[i];
for(i=0;i<number;i++)
for(j=0;j<number;j++)
arcs[i][j]=1000;
for(k=0;k<arcnum;k++)
{
cout<<"请输入边的两个顶点及边的权值: "<<endl;
cin>>vex1>>vex2>>m;
i=LocateVex(vex1);
j=LocateVex(vex2);
arcs[i][j]=m;
arcs[j][i]=m;
}
}
void Mgraph::DFS(int i=0)//用递归实现
{
int j;
cout<<vexs[i]<<"------>";
visited[i]=1;
for (j=0;j<number;j++)
{
if(!(arcs[i][j]==1000)&&!visited[j])
DFS(j);
}
}
void Mgraph::DFS1(int i=0)//非递归
{
stack<int> st;
st.push(i);
while(!st.empty())
{
int j=st.top();
st.pop();
cout<<vexs[j]<<"---->";
visited[j]=1;
for(int k=0;k<number;k++)
{
if((!(arcs[j][k]==1000))&&!visited[k])
st.push(k);
}
}
}
void Mgraph::BFS(int i=0)//广度优先遍历
{
deque<int> de;
de.push_back(i);
cout<<vexs[i]<<"------>";
visited[i]=1;
while(!de.empty())
{
int k=de.front();
for(int j=0;j<number;j++)
{
if(arcs[k][j]!=1000&&!visited[j])
{
cout<<vexs[j]<<"------>";
visited[j]=1;
de.push_back(j);
}
}
de.pop_front();
}
}
int Mgraph::mini()
{
static int i;
int min=0;
for (int j=0;j<number;j++)
{
if(!visited[j])
{
if (closeedge[min].lowcost>closeedge[j].lowcost)
{
min=j;
}
}
}
i=min;
cout<<"包括边("<<closeedge[i].begvex<<","<<closeedge[i].endvex<<")";
return i;
}
void Mgraph::prim()
{
char u;
cout<<"请输入起始顶点:"<<endl;
cin>>u;
int i=LocateVex(u);
visited[i]=1;
for(int j=0;j<number;j++)
{
closeedge[j].begvex=u;
closeedge[j].endvex=vexs[j];
closeedge[j].lowcost=arcs[i][j];
}
for (int m=1;m<number;m++)
{
int n=mini();
visited[n]=1;
closeedge[n].lowcost=1000;
for (int p=0;p<number;p++)
{
if(!visited[p])
{
if(arcs[p][n]<closeedge[p].lowcost)
{
closeedge[p].lowcost=arcs[p][n];
closeedge[p].begvex=vexs[n];
}
}
}
}
}
void Mgraph::kruskal()
{
int a,b,k=0;
int min=1000;
int arcs1[20][20];
for (int m=0;m<number;m++)
visited[m]=m;//每一个顶点属于一颗树
for (int i=0;i<number;i++)
for(int j=0;j<number;j++)
arcs1[i][j]=arcs[i][j];
while (k<number-1)
{
min=1000;
for (int i=0;i<number;i++)
{
for (int j=0;j<number;j++)
{
if (arcs1[i][j]<min)
{
a=i;
b=j;
min=arcs1[i][j];
}
}
}
if (visited[a]!=visited[b])
{
cout<<"包括边("<<vexs[a]<<","<<vexs[b]<<")";
k++;
for (int n=0;n<number;n++)
{
if (visited[n]==visited[b])
visited[n]=visited[a];
}
}
else
arcs1[a][b]=arcs[b][a]=1000;
}
}
/*int Mgraph::low()
{
int m=1000;
int min=0;
int j;
for ( j=0;j<number;j++)
{
if(!visited[j])
{
if (m>dist[j].dist)
{
m=dist[j].dist;
min=j;
}
}
}
j=min;
return j;
}*/
void Mgraph::Dijkstra()
{
cout<<"请输入起始点"<<endl;
char u;
cin>>u;
int i=LocateVex(u);
visited[i]=1;
for (int j=0;j<number;j++)
{
dist[j].dist=arcs[i][j];
dist[j].nodenum=0;
}
for (j=1;j<number;j++)
{
//int m=low();
int distance=1000;
int min=0;
for (int n=0;n<number;n++)
{
if(!visited[n])
{
if (distance>dist[n].dist)
{
distance=dist[n].dist;
min=n;
}
}
}
int m=min;
visited[m]=1;
for (n=0;n<number;n++)
{
if(!visited[n])
{
if((dist[m].dist+arcs[m][n])<dist[n].dist)
{
dist[n].dist=dist[m].dist+arcs[m][n];
dist[n].nodenum=0;
for (int x=0;x<dist[m].nodenum;x++)
{
dist[n].way[x]=dist[m].way[x];
dist[n].nodenum++;
}
dist[n].way[dist[n].nodenum++]=vexs[m];
}
}
}
}
//输出功能
for (int n=0;n<number;n++)
{
if (n!=i)
{
if(dist[n].dist<1000)
{
cout<<vexs[i]<<"到"<<vexs[n]<<"的最近距离为:"<<dist[n].dist<<endl;
cout<<"经过的顶点为:"<<vexs[i]<<"---->";
for (int p=0;p<dist[n].nodenum;p++)
{
cout<<dist[n].way[p]<<"----->";
}
cout<<vexs[n]<<endl;
}
else
cout<<vexs[i]<<"到"<<vexs[n]<<"没有通路"<<endl;
}
}
}
void Mgraph::Floyd()
{
int i,j,m,n;
for ( i=0;i<number;i++)
for ( j=0;j<number;j++)
for (m=0;m<number;m++)
P[i][j][m]=0;
for ( i=0;i<number;i++)
for ( j=0;j<number;j++)
{
D[i][j]=arcs[i][j];
if(D[i][j]<1000)
{
P[i][j][i]=1;
P[i][j][j]=1;
}
}
for ( i=0;i<number;i++)
for ( j=0;j<number;j++)
for (m=0;m<number;m++)
{
if (i==j||j==m||i==m)
continue;
if (D[i][m]+D[m][j]<D[i][j])
{
D[i][j]=D[i][m]+D[m][j];
for (n=0;n<number;n++)
{
P[i][j][n]=P[i][m][n]||P[m][j][n];
}
}
}
for ( i=0;i<number;i++)
for ( j=0;j<number;j++)
{
if (D[i][j]<1000)
{
cout<<vexs[i]<<"到"<<vexs[j]<<"的最近距离为:"<<D[i][j]<<endl;
cout<<"经过的顶点为:";
for (m=0;m<number;m++)
{
if (P[i][j][m])
{
cout<<vexs[m]<<"------>";
}
}
cout<<endl;
}
else
if (i!=j)
cout<<vexs[i]<<"到"<<vexs[j]<<"没有通路"<<endl;
}
}
int main()
{
Mgraph g;
g.CreatMGraph();
// g.print();
// g.DFS();
// g.DFS1();
// g.BFS();
// g.prim();
// g.kruskal();
// g.Dijkstra();
// g.print();
g.Floyd();
return 0;
}