-
时间:2016-04-02 17:55:33 星期六
-
题目编号:[2016-04-02][POJ][2253][Frogger]
-
题目大意:给定n个点的坐标,问从起点到终点的所有路径中,最大边的最小值是多少,即每一步至少是多少才能走到终点
-
分析:
-
方法1:
- 枚举出完全图,然后从起点跑一次Dijkstra算法,不过选点不再是选择起点到终点路径的点,而是起点到终点的路径中,边最大边最小的点,即d数组保存起点到当前点的路径中最大边的最小值,
- 最大边的最小值:u->v d[v] = min(d[i],max(d[u],g[u][v])) 即通过u -> v的所有路径的,和k -> v(k != u)的所有路径中,最大边取小的那个
- 枚举出完全图,然后从起点跑一次Dijkstra算法,不过选点不再是选择起点到终点路径的点,而是起点到终点的路径中,边最大边最小的点,即d数组保存起点到当前点的路径中最大边的最小值,
-
方法2:
- 枚举完全图,跑一次最小生成树,每次合并更新最大边
-
-
遇到的问题:
//方法1: Dijkstra
#include <queue>
#include <cstring>
#include <cstdio>
#include <cmath>
using namespace std;
const int maxn = 200 + 10;
struct Point{
int x,y;
}p[maxn];
struct Node{
int v,c;
Node(int _v = 0,int _c = 0):v(_v),c(_c){}
bool operator < (const Node & a)const{
return c > a.c;
}
};
int a[maxn][maxn],d[maxn],vis[maxn],n;
void Dijkstra(int s){
priority_queue< Node > q;
memset(vis,0,sizeof(vis));
memset(d,0x3f,sizeof(d));
d[s] = 0;
q.push(Node(s,0));
Node tmp;
while(!q.empty()){
tmp = q.top();q.pop();
int u = tmp.v;
if(vis[u]) continue;
vis[u] = 1;
for(int i = 1;i <= n ; ++i){
if(i != u && !vis[i]){
d[i] = min(d[i],max(d[u] , a[u][i]));
q.push(Node(i,d[i]));
}
}
}
}
int main(){
int cntcase = 0;
while(~scanf("%d",&n)&&n){
for(int i = 1;i <= n ;++i){
scanf("%d%d",&p[i].x,&p[i].y);
}
for(int i = 1;i <= n ; ++i){
for(int j = 1;j <= n ; ++j){
a[i][j] = (p[i].x - p[j].x)*(p[i].x - p[j].x) + (p[i].y - p[j].y)*(p[i].y - p[j].y);
}
}
Dijkstra(1);
printf("Scenario #%d\n",++cntcase);
printf("Frog Distance = %.3f\n\n",sqrt(double(d[2])));
}
return 0;
}
//方法2:并查集
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <cmath>
using namespace std;
const int maxn = 200 + 10;
const int maxm = maxn * maxn / 2;
int fa[maxn];
struct Point{
int x,y;
}p[maxn];
struct Edge{
int u,v,c;
Edge(int _u = 0,int _v = 0,int _c = 0):u(_u),v(_v),c(_c){}
bool operator < (const Edge & a)const{
return c < a.c;
}
}e[maxm];
void ini(int n){
for(int i = 0;i <= n ; ++i){
fa[i] = i;
}
}
int fnd(int x){
return fa[x] == x?x:fa[x] = fnd(fa[x]);
}
int main(){
int cntcase = 0,n;
while(~scanf("%d",&n)&&n){
for(int i = 1;i <= n ;++i){
scanf("%d%d",&p[i].x,&p[i].y);
}
int cnt = 0;
for(int i = 1;i <= n ; ++i){
for(int j = i + 1;j <= n ; ++j){
e[cnt++] = Edge(i,j,(p[i].x - p[j].x)*(p[i].x - p[j].x) + (p[i].y - p[j].y)*(p[i].y - p[j].y));
}
}
sort(e,e+cnt);
int ans = 0,f1,f2;
ini(n);
for(int i = 0;i < cnt ; ++i){
f1 = fnd(e[i].u);f2 = fnd(e[i].v);
if(f1 != f2){
fa[f1] = f2;
ans = max(ans,e[i].c);
}
if(fnd(1) == fnd(2)) break;
}
printf("Scenario #%d\n",++cntcase);
printf("Frog Distance = %.3f\n\n",sqrt(double(ans)));
}
return 0;
}
时间: 2024-12-25 01:09:47