题目链接:http://poj.org/problem?id=2253
题意:找出从1到2的最短路上边权的最小值
思路1:把所有的边预处理出来后,把边权从小到大排序,每次加一条边,等到把1和2连起来了,就得到边权的最大值啦,就和Kruskal求MST的步骤差不多。
代码如下:
#include<set>
#include<cmath>
#include<queue>
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define LL long long
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
const int INF=0x3f3f3f3f;
const int maxn = 40000+7;
double xx[maxn],yy[maxn];
struct node {
int x,y;
double len;
}a[maxn];
double Getlen(int i,int j) {
return sqrt((xx[i] - xx[j]) * (xx[i] - xx[j]) + (yy[i] - yy[j]) * (yy[i] - yy[j]));
}
bool cmp(node aa,node bb) {
return aa.len < bb.len;
}
int f[maxn];
void init(int n) {
for(int i = 1 ; i <= n ; i++) f[i] = i;
}
int Find(int x) {
if(x == f[x]) return x;
else return f[x] = Find(f[x]);
}
double Kruskal(int n , int Cnt) {
sort(a + 1 , a + Cnt + 1 , cmp);
init(n);
double ans;
for(int i = 1 ; i <= Cnt ; i++) {
int X = Find(a[i].x) , Y = Find(a[i].y);
if(X != Y) {
f[X] = Y;
}
if(Find(1) == Find(2)) {
ans = a[i].len;
break;
}
}
return ans;
}
int main() {
int n;
int cas = 0;
while(~scanf("%d",&n)) {
if(n == 0) break;
for(int i = 1 ; i <= n ; i++) {
scanf("%lf%lf" , &xx[i] , &yy[i]);
}
int cnt = 0;
for(int i = 1 ; i <= n ; i++) {
for(int j = i + 1 ; j <= n ; j++) {
a[++cnt].x = i , a[cnt].y = j;
a[cnt].len = Getlen(i , j);
}
}
printf("Scenario #%d\n" , ++cas);
printf("Frog Distance = %.3lf\n\n" , Kruskal(n , cnt));
}
return 0;
}
如果用Dijkstra求解的话,原来dist数组存的是从源点到每个端点的最短距离,那这一题就是用dist数组存从源点到每一个端点的路径距离的最大值,那么松弛条件就是
if(dist[i] > max(dist[k.v] , g[k.v][i])) {
dist[i] = max(dist[k.v] , g[k.v][i]);
pq.push(node(i,dist[i]));
}
其他的和Dijkstra完全一样啦。
具体代码:
#include <queue>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 200 + 7;
const int INF = 0x3f3f3f3f;
struct node {
int v;
double cost;
node(int _v = 0 , int _cost = 0):v(_v),cost(_cost){}
bool operator < (const node &r) const {
return cost > r.cost;
}
};
double g[maxn][maxn];
double dist[maxn];
bool vis[maxn];
priority_queue<node>pq;
void Dijkstra(int n,int start) {
for(int i = 1 ; i <= n ; i++) {
dist[i] = INF;
vis[i] = false;
}
dist[start] = 0;
while(!pq.empty()) pq.pop();
pq.push(node(start,0));
node k;
while(!pq.empty()) {
k = pq.top();
pq.pop();
if(vis[k.v]) continue;
vis[k.v] = true;
for(int i = 1 ; i <= n ; i++) {
if(dist[i] > max(dist[k.v] , g[k.v][i])) {
dist[i] = max(dist[k.v] , g[k.v][i]);
pq.push(node(i,dist[i]));
}
}
}
}
double xx[maxn] , yy[maxn];
double Getlen(int i,int j) {
return sqrt((xx[i] - xx[j]) * (xx[i] - xx[j]) + (yy[i] - yy[j]) * (yy[i] - yy[j]));
}
int main() {
int n;
int cas = 1;
while(~scanf("%d",&n) && n) {
for(int i = 1 ; i <= n ; i++) {
scanf("%lf%lf",&xx[i],&yy[i]);
}
for(int i = 1 ; i <= n ; i++) {
for(int j = 1 ; j <= n ; j++) {
g[i][j] = Getlen(i,j);
}
}
Dijkstra(n,1);
printf("Scenario #%d\n",cas++);
printf("Frog Distance = %.3f\n\n",dist[2]);
}
return 0;
}