HDUOJ1874 畅通工程续 和 NYOJ 115 城市平乱【Dijkstra 算法】

原创 2012年03月29日 08:55:39

原题链接:nyoj 115:http://acm.nyist.net/JudgeOnline/problem.php?pid=115      hduoj  1874: http://acm.hdu.edu.cn/showproblem.php?pid=1874

  一、Dijkstra 算法的介绍

    Dijkstra 算法,又叫迪科斯彻算法(Dijkstra),
    算法解决的是有向图中单个源点到其他顶点的最短路径问题。
   举例来说,
   如果图中的顶点表示城市,而边上的权重表示著城市间开车行经的距离,
   Dijkstra 算法可以用来找到两个城市之间的最短路径。

二、Dijkstra 的算法实现

Dijkstra 算法的输入包含了一个有权重的有向图 G,以及G中的一个来源顶点 S。
我们以 V 表示 G 中所有顶点的集合,以 E 表示G 中所有边的集合。
(u, v) 表示从顶点 u 到 v 有路径相连,而边的权重则由权重函数 w: E → [0, ∞] 定义。

因此,w(u, v) 就是从顶点 u 到顶点 v 的非负花费值(cost),边的花费可以想像成两个顶点之间的距离。
任两点间路径的花费值,就是该路径上所有边的花费值总和。

已知有 V 中有顶点 s 及 t,Dijkstra 算法可以找到 s 到 t 的最低花费路径(例如,最短路径)。
这个算法也可以在一个图中,找到从一个顶点 s 到任何其他顶点的最短路径。

三、图文解析 Dijkstra 算法

 ok,经过上文有点繁杂的信息,你还并不对此算法了如指掌,清晰透彻。
没关系,咱们来幅图,就好了。请允许我再对此算法的概念阐述下,

Dijkstra算法是典型最短路径算法,用于计算一个节点到其他所有节点的最短路径。
不过,针对的是非负值权边。

主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止。
[Dijkstra算法能得出最短路径的最优解,但由于它遍历计算的节点很多,所以效率低。]

ok,请看下图:

如下图,设A为源点,求A到其他各所有一一顶点(B、C、D、E、F)的最短路径。线上所标注为相邻线段之间的距离,即权值。

(注:此图为随意所画,其相邻顶点间的距离与图中的目视长度不能一一对等)

               Dijkstra无向图


算法执行步骤如下表

 是不是对此Dijkstra 算法有不错的了解了。。。讲解就到这里了。。

讲解参考:http://blog.csdn.net/v_JULY_v/article/details/6096981

现在说说oj这两个题:

nyoj  115: 懂了dijkstra 后该题没啥难度了,以暴乱城市为 起点 执行一次  求他到各个城市的最短距离,再找出有部队的城市,找到一个最小路 输出即可。。

代码:

 
#include<stdio.h>
#include<string.h>
int budui[105],ok[1005][1005];
int ac[1005],yi[1005];
int main()
{
	int a,b,c,i,j,N,M;
	int m,P,Q,K,k,min;
	scanf("%d",&K);
	while(K--)
	{
		memset(ok,999999,sizeof(ok));//初始化正无穷大
		memset(ac,0,sizeof(ac));
		memset(yi,999999,sizeof(yi));
		scanf("%d%d%d%d",&N,&M,&P,&Q);
			for(a=1;a<=N;a++)
			scanf("%d",&budui[a]);
	    for(a=1;a<=P;a++)
		{
			scanf("%d%d%d",&i,&j,&k);
            ok[i][j]=k;
			ok[j][i]=k;
		}
		yi[Q]=0;
		ac[Q]=1;
		m=M-1;
		b=Q;
		while(m--)//执行m次,找到暴乱城市到所有城市的最短时间
		{
			for(a=1;a<=M;a++)
			{
				if(ac[a]==0)
				{
					if(yi[a]>yi[b]+ok[a][b])
						yi[a]=yi[b]+ok[a][b];
				}
				
			}
			int min1=9999,loop;
			for(c=1;c<=M;c++)
			{
				if(min1>yi[c]&&ac[c]==0)
				{min1=yi[c];loop=c;}
			}
			ac[loop]=1;
			b=loop;
		}
		 min=9999;
		for(a=1;a<=N;a++)//从有部队的城市中找个最短时间
		{
			if(min>yi[budui[a]])
				min=yi[budui[a]];
		}
		printf("%d\n",min);
	}
}
        

     HDUOJ  1874:

    这个题 有点那个什么。。卡了我很久呀!!!还是题意没搞透彻。。⊙﹏⊙。。先用并查集 来判断 题中的S T,是否可以连通。不会并查集的可看我另一篇讲并查集的博客,自己找一下。若不连通,后面就不用执行了,直接下一次循环。。还有个让人蛋疼的条件就是两个城市之间 可能不止一条路!!就是在赋值时加上一个 i f 判断。。

代码:

#include<stdio.h>
#include<string.h>
int ok[1500][1500];
int ac[1505],yi[1500];
int father[1500];
int find(int x)
{
	while(x!=father[x])
		x=father[x];
	return x;
}
void hebing (int x,int y)
{
	x=find(x);
	y=find(y);
	if(x!=y)
		father[x]=y;
}
int main()
{
	int a,b,c,i,j,N,M;
	int m,k,min;
	while(~scanf("%d%d",&N,&M))
	{
		
		memset(ok,9,sizeof(ok));
		memset(ac,0,sizeof(ac));
		memset(yi,9,sizeof(yi));
		for(a=0;a<N;a++)
			father[a]=a;
	    for(a=1;a<=M;a++)
		{
			scanf("%d%d%d",&i,&j,&k);
			if(ok[i][j]>k)
                 ok[i][j]=k;
			if(ok[j][i]>k)
			     ok[j][i]=k;
			hebing(i,j);
		}
		scanf("%d%d",&i,&j);
		if(find(i)!=find(j))
		{printf("-1\n");continue;}
		yi[i]=0;
		ac[i]=1;
		m=N-1;
		b=i;
		while(m--)
		{
			for(a=0;a<N;a++)
			{
				if(ac[a]==0)
				{
					if(yi[a]>yi[b]+ok[a][b])
						yi[a]=yi[b]+ok[a][b];
				}
				
			}
			int min1=9999999,loop;
			for(c=0;c<N;c++)
			{
				if(min1>yi[c]&&ac[c]==0)
				{min1=yi[c];loop=c;}
			}
			ac[loop]=1;
			b=loop;
			if(b==j)
			{break;}
		}
		 printf("%d\n",yi[j]);
	}
}


nyoj115 城市平乱(dijkstra算法)

题目115 题目信息 运行结果 本题排行 讨论区 城市平乱 时间限制:1000 ms  |  内存限制:65535 KB 难度:4 描述 南将军统领着N个部队,这N个部队分别驻扎...

hdu 1874 畅通工程续 dijkstra算法

点击打开链接题目链接 畅通工程续 Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/O...

畅通工程续HDU杭电1874【dijkstra算法 || SPFA】

http://acm.hdu.edu.cn/showproblem.php?pid=1874 Problem Description 某省自从实行了很多年的畅通工程计划后,终于修建了很多路。...

(hdu1874)畅通工程续(dijkstra算法)

Problem Description 某省自从实行了很多年的畅通工程计划后,终于修建了很多路。不过路多了也不好,每次要从一个城镇到另一个城镇时,都有许多种道路方案可以选择,而某些方案要比另一些方案行...

hdu1874 畅通工程续 单源最短路径(SSSP)Dijkstra算法

hdu1874 畅通工程续
  • gwq5210
  • gwq5210
  • 2014年10月14日 14:57
  • 494

hdu 1874畅通工程续(dijkstra算法)

畅通工程续 Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Su...

HDU 1874 畅通工程续 / dijkstra算法 最短路实现

dijkstra算法实现以及图解

【解题报告】HDU 1874 畅通工程续 -- Dijkstra算法详解 单源点最短路问题

此题Dijkstra算法,一次AC。这个算法时间复杂度O(n2)附上该算法的演示图(来自维基百科): 附上:  迪科斯彻算法分解(优酷) problem link -> HDU 1874 /...

hdu 1874 畅通工程续 (dijkstra算法)

畅通工程续 Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Subm...
  • ren_hui
  • ren_hui
  • 2013年07月25日 22:43
  • 461

HDU1874畅通工程续 (Dijkstra算法求最短路)

#include #include #include #include using namespace std; const int inf = 100000000; const int ma...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:HDUOJ1874 畅通工程续 和 NYOJ 115 城市平乱【Dijkstra 算法】
举报原因:
原因补充:

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