图的综合实验(Dijkstra算法)

原创 2013年12月03日 11:06:05

Problem:

     给定n个村庄之间的交通图。若村庄ij之间有路可通,则ij用边连接,边上的权值Wij表示这条道路的长度。现打算在这n个村庄中选定一个村庄建一所医院。编写如下算法:(村庄为无向图,但所写算法对于其加强命题有向图也须成立)

(1) 求出该医院应建在哪个村庄,才能使距离医院最远的村庄到医院的路程最短。

(2) 求出该医院应建在哪个村庄,能使其它所有村庄到医院的路径总和最短。

Tips:

     对于(1),可以先求出每个村庄到其它所有村庄的最短路径,保存其最大值(表示假设医院建在该村庄,距离医院最远的村庄的路径长度);然后在这些最大值中找出一个最小值。

    对于(2),可以先求出每个村庄到其它所有村庄的最短路径,保存其累加和(表示假设医院建在该村庄,其它所有村庄距离医院的路径总和);然后在这些和中找出一个最小值。

#include<stdio.h>
#define	INF	1000000
#define UINF -1000000
#define MAXV 100
//创建最短路径返回值的结构体
typedef struct
{
	int dist[MAXV],path[MAXV];
	int s[MAXV],n,v;
}DijValue;
//创建图
typedef struct
{	int edges[MAXV][MAXV];
	int n;
}MGraph;

void CreateGraph(MGraph &g)
{	int i,j;
	printf("输入村庄个数:");
	scanf("%d",&g.n);  
	printf("输入路径权值(若不直接相连输入-1)\n");
	for(i=0;i<g.n;i++) 
	{	printf("\t依次输入顶点%d到顶点0~%d的权值:",i,g.n-1);
		for(j=0;j<g.n;j++)
		{
			scanf("%d",&g.edges[i][j]);
			if(g.edges[i][j]==-1)
				g.edges[i][j]=INF;
		}
		printf("\n");
	}
}
//输出路径
void Ppath(int path[],int k,int v)
{   int i;
	i=path[k];
	if(i==v){printf("%d=>%d",i,k);return;}
	Ppath(path,i,v);
	printf("=>%d",k);
}

//最短路径算法
void Dijkstra (MGraph g,int v,DijValue *Temp)
{	int dist[MAXV],path[MAXV];
	int s[MAXV];
	int mindis,i,j,u;
	for(i=0;i<g.n;i++)
	{	dist[i]=g.edges[v][i];
		s[i]=0;
		if(g.edges[v][i]<INF)
			path[i]=v;    		
		else
			path[i]=-1;			//i与v没边时置i前一个顶点为-1
	}
	s[v]=1;path[v]=v;			
	for(i=0;i<g.n;i++)
	{	mindis=INF;
		for(j=0;j<g.n;j++)		//寻找新最短dist[]到S中
			if(s[j]==0&&dist[j]<mindis)
			{	u=j;
				mindis=dist[j];
			}
			s[u]=1;
			for(j=0;j<g.n;j++)	//新一轮的dist[]
				if(s[j]==0)
					if(g.edges[u][j]<INF&&dist[u]+g.edges[u][j]<dist[j])
					{	dist[j]=dist[u]+g.edges[u][j];
						path[j]=u;
					}
	}
	Temp->n=g.n;
	Temp->v=v;
	for(int k=0;k<g.n;k++)
	{
		Temp->dist[k]=dist[k];
		Temp->path[k]=path[k];
		Temp->s[k]=s[k];
	}
}
//问题一:距离医院最远的村庄到医院的路程最短
void Question_One(MGraph g)
{
	int i,j,flag=1,item;
	int max=UINF;
	int min=INF;
	int Number,Number2;
	DijValue Temp1;
	printf("Question1:\n");
	for(i=0;i<g.n;i++)
	{
		Dijkstra(g,i,&Temp1);
		for(j=0;j<g.n;j++)							//求每个医院最远村庄
		{
			if(Temp1.s[j]==1&&Temp1.dist[j]>max)
			{	max=Temp1.dist[j];
				item=j;
			}
		}
		if(flag){printf("\t从每个村庄出发的最短路径的最长值:\n\t");flag=0;}
		printf("long[%d]=%d  ",i,max);
		if(max<min)									//最远村庄中的最近的
		{
			min=max;
			Number=i;
			Number2=item;
		}
		max=UINF;
	}
	printf("\n\t所以距离医院最远的村庄的最近路程为:\n\tlong[%d]=%d\n",Number,min);
	Dijkstra(g,Number,&Temp1);
	printf("\t具体路线为:");
	Ppath(Temp1.path,Number2,Number);				//输出路径
	printf("\n");
}
//问题二:所有村庄到医院的路径总和最短
void Question_Two(MGraph g)
{
	int i,j,sum=0,flag=1;
	int min=INF;
	int Number;
	DijValue Temp2;
	printf("Question2:\n");
	for(i=0;i<g.n;i++)
	{
		Dijkstra(g,i,&Temp2);
		for(j=0;j<g.n;j++)							//路程和
		{
			if(Temp2.s[j]==1)
				sum+=Temp2.dist[j];
		}
		if(flag){printf("\t从各自每个村庄出发的路程总和:\n\t");flag=0;}
		printf("sum[%d]=%d  ",i,sum);
		if(sum<min)									//最小路程和
		{
			min=sum;
			Number=i;
		}
		sum=0;
	}
	printf("\n\t所以到其它所有村庄路径总和最短的村庄:\n\tsum[%d]=%d\n",Number,min);
}
int main(void)
{   int sovle,flag=1;
	MGraph graphMin;
	while(flag)
	{   
		printf("\t\t\t\t求解--1,退出--0:");
		scanf("%d",&sovle);
		switch(sovle)
		{   case 0:flag=0;break; 
			case 1:
				{	CreateGraph(graphMin);
				    Question_One(graphMin);
				    Question_Two(graphMin);
					break;
				}
		}
	}
	return 0;
}


版权声明:本文为博主原创文章,未经博主允许不得转载。

Dijkstra算法——《算法导论》学习心得(十三)

这两天在做一个项目,关于北京市出租车的,然后用到了Dijkstra算法,所以这篇文章就先写Dijkstra算法了。在大二下的时候学了数据结构,书里面也讲了Dijkstra算法,但是当时怎么也没理解,结...
  • tangbo713
  • tangbo713
  • 2014年12月21日 19:30
  • 1372

经典算法之图的最短路径(一):Dijkstra算法

Dijkstra算法可以说基本上每一本有讲到图的最短路径的书上都会有的一个算法,但基本上都是讲原理和伪代码,今天自己用Java代码给实现了一下,记录在此。 Dijkstra算法只是解决某些图的最短路径...
  • silent_strings
  • silent_strings
  • 2015年09月01日 15:50
  • 2813

数据结构:单源最短路径--Dijkstra算法

单源最短路径 给定一带权图,图中每条边的权值是非负的,代表着两顶点之间的距离。指定图中的一顶点为源点,找出源点到其它顶点的最短路径和其长度的问题,即是单源最短路径问题。 Dijkstra算法...
  • zhangxiangDavaid
  • zhangxiangDavaid
  • 2014年08月03日 21:28
  • 2322

通俗算法讲解之图最短路径——Dijkstra算法

Dijkstra算法计算单源有向正权值图最短路径计算
  • qq_26849233
  • qq_26849233
  • 2016年10月27日 19:05
  • 810

poj 2387 Dijkstra入门(动态图解)

Til the Cows Come Home Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 43861   Ac...
  • Summer__show_
  • Summer__show_
  • 2016年07月28日 15:24
  • 529

图论--Dijkstra算法----邻接表实现

Djistra算法                输入的权值不能为负。 C语言实现:                  算法外部有所改动,核心算法没有改。 声明:            ...
  • yjy188
  • yjy188
  • 2012年10月21日 11:28
  • 1476

最短路径(邻接表)-Dijkstra算法

最短路径(邻接表)-Dijkstra算法:生成的图采用邻接表的存储方式。        具体的实现代码如下: package com.threeTop.www; import java.util...
  • u012017783
  • u012017783
  • 2017年04月26日 17:04
  • 1011

dijkstra算法心得

基本思想 通过Dijkstra计算图G中的最短路径时,需要指定起点s(即从顶点s开始计算)。 此外,引进两个集合S和U。S的作用是记录已求出最短路径的顶点(以及相应的最短路径长度),而U则是记录还未求...
  • qq_32792879
  • qq_32792879
  • 2016年07月19日 16:15
  • 413

有向图最短路Dijkstras算法过程动态演示

/********************************************** 2015.1.9---1.12 by yzk ***********************...
  • u011498819
  • u011498819
  • 2015年01月12日 16:28
  • 1621

最短路径之Dijkstra算法及实例分析

Dijkstra算法迪科斯彻算法 Dijkstra算法描述为:假设用带权邻接矩阵来表示带权有向图。首先引进一个辅助向量D,它的每个分量D[i]表示当前所找到的从始点v到每个终点Vi的最短路径。它的初始...
  • u010758724
  • u010758724
  • 2014年03月27日 15:30
  • 5447
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:图的综合实验(Dijkstra算法)
举报原因:
原因补充:

(最多只允许输入30个字)