问题描述:
给定n个村庄之间的交通图,若村庄i和村庄j之间有道路,则将顶点i和顶点j用边连接,边上的权Wij 表示这条道路的长度。现在要从这n个村庄选择一个村庄建一所医院,问这所医院应建在哪个村庄,才能使离医院最远的村庄到医院的距离最短?试设计一个算法来解决该问题。
#include<iostream.h>
#define MAX_WEIGHT 1000 //边的权值超过此值就表示没有直接相连
#define MAX_VERTEX_NUM 20//村庄数
bool P[MAX_VERTEX_NUM][MAX_VERTEX_NUM][MAX_VERTEX_NUM];
struct ArcWeight{
double adj;//边的权值
};
struct MGraph{
char vexs[MAX_VERTEX_NUM];//村庄名称
ArcWeight arcs[MAX_VERTEX_NUM][MAX_VERTEX_NUM];//邻接矩阵(边)
int vexnum;//村庄数
int arcnum;//村庄之间的路径数目
};
//各函数的声明
void createUND(MGraph&G);
int LocateVex(MGraph G,char v);
void ShortestPath_FLOYD(MGraph G);
double compare(double s[],MGraph G);
void short_compare(double l[],MGraph G);
void createUND(MGraph&G){//采用邻接矩阵表示法构造无向网
int i,j,k;
double w;
char v1,v2;
cout<<"请输入村庄数n:";cin>>G.vexnum;
// int n=G.vexnum;
// int m=n(n-1)/2;
cout<<"请输入村庄之间的路径数m(m<=n(n-1)/2):";cin>>G.arcnum;
cout<<"请输入村庄名称(名称之间用空格符隔开,如:a b c):";
for(i=0;i<G.vexnum;i++)
cin>>G.vexs[i];
for(i=0;i<G.vexnum;i++)
for(j=0;j<G.vexnum;j++)
G.arcs[i][j].adj=MAX_WEIGHT;
cout<<"请输入各条道路连通的两个村庄的名称及其权值(如:ab 5 注意:村庄之间必须连通!):"<<endl;
for(k=0;k<G.arcnum;k++){
cin>>v1>>v2>>w;
i=LocateVex(G,v1);
j=LocateVex(G,v2);
G.arcs[i][j].adj=w;
G.arcs[j][i].adj=w;
}
cout<<endl;
}
int LocateVex(MGraph G,char v){//顶点(村庄)在图中的位置
int i;
for(i=0;i<G.vexnum;i++)
if(v==G.vexs[i]) return i;
return -1;
}
void ShortestPath_FLOYD(MGraph G) { //求最短路径
//P[v][w]是各对顶点v和w之间的最短路径
double D[MAX_VERTEX_NUM][MAX_VERTEX_NUM],s[MAX_VERTEX_NUM],l[MAX_VERTEX_NUM];// 带权长度D[v][w]。
int v,w,u,i,j,k; //u是v,w中间的村庄
j=k=0;
cout<<"各村到最远村庄的最短距离为:"<<endl;;
for (v=0; v<G.vexnum; ++v) // 各对结点之间初始已知路径及距离
for (w=0; w<G.vexnum; ++w) {
D[v][w] = G.arcs[v][w].adj;
for (u=0; u<G.vexnum; ++u) P[v][w][u] = false;
if (D[v][w] < MAX_WEIGHT) { // 从v到w有直接路径
P[v][w][v] = P[v][w][w] = true;//若P[v][w][u]为TRUE,则u是从v到w当前求得最短路径上的顶点
}
}
for (u=0; u<G.vexnum; ++u){
if(u!=G.vexnum-1){
for (v=0; v<G.vexnum; ++v)
for (w=0; w<G.vexnum; ++w)
if (D[v][u]+D[u][w] < D[v][w]) { // 从v经u到w的一条路径更短
D[v][w] = D[v][u]+D[u][w];
for (i=0; i<G.vexnum; ++i)
P[v][w][i] =(P[v][u][i] || P[u][w][i]);
}
}
else{
for (v=0; v<G.vexnum; ++v){
k=0;s[k]=0;
for (w=0; w<G.vexnum; ++w){
if (D[v][u]+D[u][w] < D[v][w]) {
D[v][w] = D[v][u]+D[u][w];
for (i=0; i<G.vexnum; ++i)
P[v][w][i] =(P[v][u][i] || P[u][w][i]);
}
if(v!=w) {
cout<<G.vexs[v]<<"->"<<G.vexs[w]<<" "<<D[v][w]<<endl;
s[k]=D[v][w];k++;
}
}
l[j]=compare(s,G);
cout<<G.vexs[v]<<"到最远的村庄的最短距离为:"<<l[j]<<endl;
j++;
cout<<endl;
}
}
}
short_compare(l,G);
}
double compare(double s[],MGraph G){//求最远村庄的距离
double max=s[0];
int k;
for(k=0;k<G.vexnum;k++)
if(s[k]>max) max=s[k];
return max;
}
void short_compare(double l[],MGraph G){//选择使离医院最远的村庄到医院的路程最短
double min=l[0];
int j,t=0;
for(j=0;j<G.vexnum;j++)
if(l[j]<min){ min=l[j];t=j;}
cout<<"因此,医院应建在"<<G.vexs[t]<<"处"<<endl;
}
void main(){ //主函数
MGraph G;
createUND(G);
ShortestPath_FLOYD(G);
}