图的综合实验(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;
}


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

相关文章推荐

Oracle基础学习笔记(二)

二、表空间 表空间是数据库的逻辑划分,所有的数据库对象都存放在指定的表空间中。SQL Server、MySQL等数据库是没有表空间的概念的,Oracle数据库开创性的提出了表空间的设计理念。事实上,...
  • N_P_C
  • N_P_C
  • 2016年05月30日 15:58
  • 268

Oracle基础学习笔记(一)

接触oracle不久,近段时间边看资料学习边记录笔记,正所谓好记性不如烂笔头嘛。稍微整理了下这两天学习的内容,以后回过头来翻一翻这些基础知识,感觉还是比较有意义的。 我本地下载是oracle11g的...
  • N_P_C
  • N_P_C
  • 2016年05月27日 08:53
  • 271

第2次实验——算法基本功与综合思考

(1)算法基本功——快速排序     对文件 largeW.txt(下载链接)中的数据,应用快速排序算法进行排序,并与冒泡排序、归并排序进行时间比较。体验算法复杂度对设计算法的影响。 代码...

第2次实验——算法基本功 与 综合思考

实验内容(4选2即可,推荐多完成一些) (1)算法基本功——快速排序     对文件 largeW.txt(下载链接)中的数据,应用快速排序算法进行排序,并与冒泡排序、归并排序进行时间比较...

第2次实验——算法基本功 与 综合思考

(3)算法综合实践——搜索引擎     上网搜索有关“搜索引擎”的相关资料,包括但不限于以下方面(至少要有2个方面):搜索引擎岗位要求、搜索引擎工作原理、搜索引擎涉及到教材中哪些算法、搜索引擎的...

:第2次实验——算法基本功 与 综合思考

1. 时针分针重合几次 表面上有60个小格,每小格代表一分钟, 时针每分钟走1/12小格,分针每分钟走1小格,从第一次重合到第二次重合分针比时针多走一圈即60小格,所以 60/(1-...

第2次实验——算法基本功 与 综合思考

(3)算法综合实践——搜索引擎     上网搜索有关“搜索引擎”的相关资料,包括但不限于以下方面(至少要有2个方面):搜索引擎岗位要求、搜索引擎工作原理、搜索引擎涉及到教材中哪些算法、搜索引擎的...

第二次实验--算法基本功与综合思考

(3)算法综合实践——搜索引擎 工作原理: 搜索引擎的基本工作原理包括如下三个过程:首先在互联网中发现、搜集网页信息;同时对信息进行提取和组织建立索引库;再由检索器根据用户输入的查询关键字...

计科1111-1114班第二次实验作业(算法基本功 与 综合思考)

实验课安排      地点: 科技楼423     时间:  计科3-4班---15周周一上午、周二下午                计科1-2班---15周周一下午、周二晚上(晚...

计科1111-1114班第二次实验作业(算法基本功 与 综合思考)

package ceshi; import java.util.ArrayList; import java.util.Scanner; public class EightQueens...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:图的综合实验(Dijkstra算法)
举报原因:
原因补充:

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