poj2253

中间有个不可以提前退出的问题,求教大神啊,想不出来。。。

/*在utility中已经定义了pair的操作符,大小比较是先比较第一个元素,第一个元素相等时,比较第二个元素
也可以重载操作符*/
//利用最小队列进行优化
//dijkstar这种思想真的可以解决好多问题啊。。。。
/*主要思想:对点进行松弛,dist[v]表示到达v的路径上的最大边,v的直接前驱节点是u,则dist[v]如果
大于length[u][v]或者是dist[u]则表示需要松弛,将dist[v]缩小,变成经过u结点的路径,这样最大路径的值
缩小,最大路径的长度取决于length[u][v]和dist[u]中的较大数。*/
#include <iostream>
#include <vector>
#include <queue>
#include <math.h>
#include <utility>
#include <cstring>
#define MAX 204
#define pdi pair<double,int>//注意定义的格式
const int INF=10000000;
using namespace std;
double maxOne(double a,double b)//注意这里是double不是int
{
	return a>b?a:b;
}
int main()
{
	int numOfStones,count=0;
	double length[MAX][MAX],x[MAX],y[MAX],flag[MAX],dist[MAX];
	priority_queue<pdi ,vector<pdi> ,greater<pdi> > q;
	pdi temp;
	while (cin >> numOfStones && numOfStones >0)
	{
		count++;
		int i=1,n=numOfStones;
		memset(flag,0,sizeof(flag));
		for (int m=1;m<=numOfStones;m++)
			dist[m]=INF;
		while (numOfStones--)
		{
			cin >> x[i] >> y[i];
			++i;
		}
		for (i=1;i<=n;i++)
		{
			for (int j=1;j<=n;j++)
			{
				//求出任意两点之间的距离;
				length[i][j]=sqrt((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]));
			}
		}
		dist[1]=0;
		temp.first=0;
		temp.second=1;
		q.push(temp);
		while (!q.empty())
		{
			temp=q.top();
			q.pop();
			int minVer=temp.second;
			int minLength=temp.first;
			flag[minVer]=1;
			//if(minVer==2) break;为什么不可以提前跳出。按理说到这里的话,2已经找到了
			//也已经标记了后面的就不会对它进行松弛啊,还没有想出来反例。。。。
			for (int k=1;k<=n;++k)
			{
				if(!flag[k]&&dist[k]>maxOne(length[minVer][k],dist[minVer]))
				{
					dist[k]=maxOne(length[minVer][k],dist[minVer]);
					//只有松弛过的点才对后面有影响,没有松弛的点分为两类,一类是已经被标记的点,这类
					//点已经找到到达这个点的最大路径的最小值,第二类是没有标记,但是没有经过松弛的点
					//就是这个点的dist没有改变,那么从这个点对其他点进行松弛也是不会改变的,是没有
					//影响的,不用加入到队列中改进行再一次的松弛操作
					q.push(make_pair(dist[k],k));
				}
			}
		} 
		cout << "Scenario #" << count << endl;
		printf("Frog Distance = %.3lf\n\n",dist[2]);
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值