松弛操作
- 这道题目也是一道比较典型的dij题目,利用松弛操作,我们可以得到:
假设存在一条从
a→b
a
→
b
的边,则可以利用这条边进行松弛
b.d=max(b.d,a.d,w(a,b))
b
.
d
=
m
a
x
(
b
.
d
,
a
.
d
,
w
(
a
,
b
)
)
- 在初始化double为最大值的时候,不能用
memset(a, 0x3f3f3f3f, sizeof(a))
,这样得到是一样小数,
详细请参考
IEEE754
I
E
E
E
754
#include <iostream>
#include <math.h>
#include <string.h>
#include <stdio.h>
#include <vector>
using namespace std;
int n;
const int size = 200;
double road[size][size];
double dis[size];
int visit[size];
const int INF = 0x3f3f3f3f;
struct Node{
int x, y;
Node(int x,int y):x(x),y(y){}
};
int MAX(int x,int y){
return x>y?x:y;
}
double POW(int x){
return x*x*1.0;
}
vector<Node> nodelist;
double getdis(int i, int j){
Node node1 = nodelist[i];
Node node2 = nodelist[j];
double d = sqrt(POW(node1.x - node2.x) + POW(node1.y - node2.y));
return d;
}
double dij(){
memset(visit, 0, sizeof(visit));
for (int i = 0; i < n; ++i) {
dis[i] = road[0][i];
}
visit[0] = 1;
for (int i = 0; i < n - 1; ++i) {
double val = INF; int u;
for (int j = 0; j < n; ++j) {
if (!visit[j]&&val>dis[j])
val = dis[u=j];
}
visit[u] = 1;
for (int k = 0; k < n; ++k) {
if (!visit[k]&&dis[k]>MAX(dis[u],road[u][k])){
dis[k] = max(dis[u],road[u][k]);
}
}
}
return dis[1];
}
int main(){
freopen("../in.txt", "r", stdin);
int index = 0;
while (scanf("%d", &n)&&n){
memset(road, INF, sizeof(road));
for (int i = 0; i < n; ++i) {
road[i][i] = 0;
}
int x,y;
for (int i = 0; i < n; ++i) {
scanf("%d %d", &x, &y);
nodelist.push_back(Node(x,y));
}
for (int i = 0; i < nodelist.size(); ++i) {
for (int j = i+1; j < nodelist.size(); ++j) {
road[i][j] = road[j][i] = getdis(i, j);
}
}
double d = dij();
printf("Scenario #%d\n", ++index);
printf("Frog Distance = %.3lf", d);
cout<<endl<<endl;
nodelist.clear();
}
}