Dijkstra算法变形
题目大意:
一个直角坐标系,给出所有点的坐标,以及两个确定的点,问从一个点到另一个点使经过的边中最长的边尽可能短,最短为多少。 点数n<1000,测试实例数200 .
一开始的错误思路:
1假设A为起点B为终点
2算出所有的点之间的距离O(n^2)
3把各个点和A点之间的距离按照从小到大的顺序排序O(nlogn)
4从小到大依次确定每一个点到A点的最长边的最小可能值。
错误原因:
第4步,从小到大确定每个点的距离不一定是最小可能值,因为,有可能边1-4通过边1-2松弛后变成1-2-4的最小距离,可能比边1-3通过边1-2松弛之后变成1-2-3的最小距离还要小。即使边1-4本来比边1-3长。
改正后思路:
只有每次松弛得出来的到A的距离最短的点,才是确定点。
关于dijkstra:
这个算法可以求出所有点到一个确定点的“最短距离”(为什么加引号就是因为这个最短距离可以扩展成其他的概念,如这道题)。
比如要确定各个点到1的最小距离,首先找出1-2,1-3,1-4...里面最小的,1-2,那么这个2点到1点的最小距离就确定了,就是这个数(因为如果不是,那用别的路就先要到别的点,这里就已经超过1-2了)。然后就是用点2的所有出边,看能不能再把其他的1-i通过1-2-i变短。之后再找出最短的,再继续判断这个点的所有出边。
这里的两个问题:
1.边1-2是封装好的,表示的不再是1-2的直接距离,而是1-2的间接距离(即中间可以通过各个点,使得这段距离最短的值)。
2.为什么不会存在边1-m-i<边1-2-i(m≠2)?
情况1:这个m如果到原点的距离已经确定了,那么,之前就已经判断过了(m比2先判断出边),在那个时候,1-i的值就已经封装成了1-m-i。

情况2:如果这个m到原点的距离还没有确定,那么,我先把1-i封装成1-2-i之后再和1-m-i来比也没有什么影响,不行再改呗~

#include
#include
#include
#include
#define N 300
#define inf 0x3f3f3f3f
using namespace std;
struct point
{
	int x;
	int y;
}pot[N]; 
int cs=0;
double dis[N][N]={0};//dis[i][j]表示从j到i之间的边的最长边的可能达到的最小值 
int n;
int vis[N]={0};//记录0到i的距离是否确定下来了 


void input()
{
	for(int i=0;idis[v][j]&&dis[0][j]>dis[0][v])//如果v到0的距离大于j到0的距离,并且也大于v到j的距离 
			{
				dis[0][j]=dis[j][0]=max(dis[v][j],dis[0][v]);
			}
			 
			if(min>dis[0][j])
			{
				min=dis[0][j];
				minx=j;
			}
		}
		vis[minx]=1;
		v=minx;
		if(minx==1)
		{
			printf("Scenario #%d\n",cs);
			printf("Frog Distance = %.3f\n\n",dis[0][1]);
			return;
		}
		
	}
		
	
	
}
int main()
{
	while(cin>>n)
	{
		cs++;
		if(n==0)break;
		input();
		dist();
		my_Dijkstra();
		memset(vis,0,sizeof(vis));
	} 
	return 0;
}

注:这道题所有的路都是通的,如果以后有不同的路,记得是枚举上一次确定的点的所有出边。