• hdoj-2066-一个人的旅行(迪杰斯特拉)


    一个人的旅行

    Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 23396    Accepted Submission(s): 8142


    Problem Description
    尽管草儿是个路痴(就是在杭电待了一年多,竟然还会在校园里迷路的人,汗~),但是草儿仍然非常喜欢旅行,由于在旅途中 会遇见非常多人(白马王子,^0^),非常多事,还能丰富自己的阅历。还能够看漂亮的风景……草儿想去非常多地方。她想要去东京铁塔看夜景。去威尼斯看电影。去阳明山上看海芋,去纽约纯粹看雪景。去巴黎喝咖啡写信,去北京探望孟姜女……眼看寒假就快到了,这么一大段时间,可不能浪费啊,一定要给自己好好的放个假,但是也不能荒废了训练啊。所以草儿决定在要在最短的时间去一个自己想去的地方。由于草儿的家在一个小镇上,没有火车经过,所以她仅仅能去邻近的城市坐火车(好可怜啊~)。

     

    Input
    输入数据有多组。每组的第一行是三个整数T,S和D。表示有T条路,和草儿家相邻的城市的有S个,草儿想去的地方有D个;
    接着有T行,每行有三个整数a,b。time,表示a,b城市之间的车程是time小时;(1=<(a,b)<=1000;a,b 之间可能有多条路)
    接着的第T+1行有S个数。表示和草儿家相连的城市。
    接着的第T+2行有D个数,表示草儿想去地方。
     

    Output
    输出草儿能去某个喜欢的城市的最短时间。
     

    Sample Input
    6 2 3 1 3 5 1 4 7 2 8 12 3 8 4 4 9 12 9 10 2 1 2 8 9 10
     

    Sample Output
    9
     解题思路
            这是一道求最短路径的问题,跟普通的最短路径不同的是这个题有多个起点,能够用for循环迪杰斯特拉来解答。
            也许会操心第一次迪杰斯特拉之后,那map数组的值不是已经发生变化了吗?第二次会受影响吗?
            答案是否定的,我们只须要初始now和ok数组就好,map数组不过存储距离,假设第一次之后map[i][j]的值为2,
            而第二次map[i][j]的值为3,非常显然我们会选择2,3直接排除掉了。
            for循环迪杰斯特拉之后的map数组是到全部地点的最短距离。不论从哪个原地出发。
    错误原因
           OJ显示Runtime Error(ACCESS_VIOLATION)。造成这个错误的原因有两个,(1)数组开小了,(2)数组被越界了
    代码
    #include<stdio.h>
    int map[1100][1100];
    int ok[1100];
    int now[1100];
    int sta[1100];
    int end[1100];
    #define max 1007
    int main()
    {
    	int t,s,d;
    	int i,j,k;
    	int nowlen,nowx;
    	int a,b,l;
    	int ans;
    	while(scanf("%d%d%d",&t,&s,&d)!=EOF)
    	{
    		for(i=1;i<=max;i++)
    		    for(j=1;j<=max;j++)
    		        map[i][j]=max;//map初始为无穷大 
    		for(i=1;i<=t;i++)
    		{
    			scanf("%d%d%d",&a,&b,&l);
    			if(map[a][b]>l)
    			    map[a][b]=map[b][a]=l;
    		}//更新给定的距离 
    		for(i=1;i<=s;i++)
    		    scanf("%d",&sta[i]);
    		for(i=1;i<=d;i++)
    		    scanf("%d",&end[i]);
    		for(i=1;i<=s;i++)
    		{//for循环迪杰斯特拉 
    			for(j=1;j<=max;j++)
    			{
    				now[j]=max;
    				ok[j]=0;
    			}
    			now[sta[i]]=0;
    			ok[sta[i]]=1;//初始now和ok 
    			for(k=1;k<=max;k++)
    			{
    			    nowlen=max;
    			    for(j=1;j<=max;j++)
    			    {
    				    if(!ok[j]&&nowlen>map[sta[i]][j])
    			 	    {
    					    nowlen=map[sta[i]][j];
    					    nowx=j;
    				    }
    			    }//找到还没确定的距离之中最小的距离 
    			    now[nowx]=nowlen;
    			    ok[nowx]=1;
    			    for(j=1;j<=max;j++)
    			    {
    				    if(!ok[j]&&map[sta[i]][j]>now[nowx]+map[nowx][j])
    				        map[sta[i]][j]=now[nowx]+map[nowx][j];
    			    }//更新其它点到原点的距离 
    			}
    		}
    		ans=max;
    		for(i=1;i<=s;i++)
    		    for(j=1;j<=d;j++)
    		        if(map[sta[i]][end[j]]<ans)
    		            ans=map[sta[i]][end[j]];//找到最小的 
    		printf("%d
    ",ans);
    	}
    	return 0;
    }


  • 相关阅读:
    BZOJ 1036 树的统计 | 树链剖分模板题
    BZOJ 3295 动态逆序对 | CDQ分治
    Luogu 3810 & BZOJ 3262 陌上花开/三维偏序 | CDQ分治
    BZOJ 2152 聪聪可可 | 树的点分治
    BZOJ 2458 最小三角形 | 平面分治
    51nod 1564 区间的价值 | 分治 尺取法
    Luogu 1429 平面最近点对 | 平面分治
    Codeforces 633C Spy Syndrome 2 | Trie树裸题
    一棵简单能用的左偏树
    【网络流24题】餐巾计划(图解)
  • 原文地址:https://www.cnblogs.com/mfrbuaa/p/5416433.html
Copyright © 2020-2023  润新知