中间有个不可以提前退出的问题,求教大神啊,想不出来。。。
/*在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]);
}
}