医院选址问题 高手请进

54454hhj 2009-07-01 07:06:11
医院选址
问题描述:有n个村庄,现要从这n个村庄中选择一个村庄新建一所医院,使其余的村庄到这所医院的距离总体来说较短,设计较合理。
实现要求:可以将问题抽象为有n个接点,在这n个接点之间建立一个无向图,边上的权值w(i,j)表示村庄i到j之间道路的长度, 在无向图中n个顶点之间,最多可能设置n(n-1)/2条线路,如何在这些线路中选择n-1条线路,以使总的线路最短?对于n个顶点的连通网可以建立许多不同的无向图,每一个无向图都可以表示一个道路网,其中要选择一个最优图,使图上各边之小。

这是我们课程设计的题目 开始我是用最小生成树去写的 不过后来发现好像这道题目是要用最短路径来做 现在问题是如果用最短路径做 那题目中说选一个医院,使其余的村庄到这所医院的距离总体来说较短,主要是总体这两个字 感觉好像是说要每个结点到其余结点的最短路径之和加起来,然后再比较大小,最小的就是医院 如果是这样 想请教一下这个算法要如何实现??
...全文
825 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
zaq3838 2011-12-23
  • 打赏
  • 举报
回复
除了源程序外,还有其它的吗?
54454hhj 2009-07-01
  • 打赏
  • 举报
回复
谢谢 我也是这样想的 不过就是代码实现上有问题 脑袋都晕了 不知道能不能给一个大致的框架 谢谢!
liao05050075 2009-07-01
  • 打赏
  • 举报
回复
这题目要用最短路径算法来做。比如用dijstra算法,先对第一个结点进行计算,得到当前结点到所有结点的最短路径,然后加起来,得到当前的一个值,
然后对下一个结点同样使用dij算法,得到另一个和,最终会得到n个和,取最小那个就是了。

当然,不用dij也行,使用floyed算法直接求全路径最短路也可以
54454hhj 2009-07-01
  • 打赏
  • 举报
回复
我原来的代码是
#include <stdio.h>
#include <stdlib.h>

#define MAX 100
#define MAXCOST 0x7fffffff

int graph[MAX][MAX];

int Prim(int graph[][MAX], int n)
{
/* lowcost[i]记录以i为终点的边的最小权值,当lowcost[i]=0时表示终点i加入生成树 */
int lowcost[MAX];

/* mst[i]记录对应lowcost[i]的起点,当mst[i]=0时表示起点i加入生成树 */
int mst[MAX];

int i, j, min, minid, sum = 0;

/* 默认选择1号节点加入生成树,从2号节点开始初始化 */
for (i = 2; i <= n; i++)
{
/* 最短距离初始化为其他节点到1号节点的距离 */
lowcost[i] = graph[1][i];

/* 标记所有节点的起点皆为默认的1号节点 */
mst[i] = 1;
}

/* 标记1号节点加入生成树 */
mst[1] = 0;

/* n个节点至少需要n-1条边构成最小生成树 */
for (i = 2; i <= n; i++)
{
min = MAXCOST;
minid = 0;

/* 找满足条件的最小权值边的节点minid */
for (j = 2; j <= n; j++)
{
/* 边权值较小且不在生成树中 */
if (lowcost[j] < min && lowcost[j] != 0)
{
min = lowcost[j];
minid = j;
}
}
/* 输出生成树边的信息:起点,终点,权值 */
printf("%c - %c : %d\n", mst[minid] + 'A' - 1, minid + 'A' - 1, min);

/* 累加权值 */
sum += min;

/* 标记节点minid加入生成树 */
lowcost[minid] = 0;

/* 更新当前节点minid到其他节点的权值 */
for (j = 2; j <= n; j++)
{
/* 发现更小的权值 */
if (graph[minid][j] < lowcost[j])
{
/* 更新权值信息 */
lowcost[j] = graph[minid][j];

/* 更新最小权值边的起点 */
mst[j] = minid;
}
}
}
/* 返回最小权值和 */
return sum;
}

int main()
{
int i, j, k, m, n;
int x, y, cost;
char chx, chy;
printf("结点数:");
scanf("%d",&m);
/* 读取节点和边的数目 */
printf("边数:");
scanf("%d",&n);
getchar();

/* 初始化图,所有节点间距离为无穷大 */
for (i = 1; i <= m; i++)
{
for (j = 1; j <= m; j++)
{
graph[i][j] = MAXCOST;
}
}

/* 读取边信息 */
printf("输入权值邻接矩阵:\n");
for (k = 0; k < n; k++)
{
scanf("%c %c %d", &chx, &chy, &cost);
getchar();
i = chx - 'A' + 1;
j = chy - 'A' + 1;
graph[i][j] = cost;
graph[j][i] = cost;
}

/* 求解最小生成树 */
cost = Prim(graph, m);

/* 输出最小权值和 */
printf("最小权值和:%d\n", cost);

//system("pause");
return 0;
}

是用最小生成树写的 但是后来发现和题目不符 题目说要从N个点选一个当做医院 而我写的只是一个最小生成树 没有选医院
54454hhj 2009-07-01
  • 打赏
  • 举报
回复
我想问一下 如果没有后面那些要求 就只看题目 你觉得应该怎么做啊? 谢谢!
tanadar 2009-07-01
  • 打赏
  • 举报
回复
如果没有这句话“对于n个顶点的连通网可以建立许多不同的无向图,每一个无向图都可以表示一个道路网,其中要选择一个最优图,使图上各边之小。”那就是求最小生成树,用并查集效果最好。但是现在问题是,这句话我看不懂?

69,373

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧