时间:2016-04-02 17:55:33 星期六
题目编号:[2016-04-02][POJ][2253][Frogger]
题目大意:给定n个点的坐标,问从起点到终点的所有路径中,最大边的最小值是多少,即每一步至少是多少才能走到终点
分析:
-
- 枚举出完全图,然后从起点跑一次Dijkstra算法,不过选点不再是选择起点到终点路径的点,而是起点到终点的路径中,边最大边最小的点,即d数组保存起点到当前点的路径中最大边的最小值,
- 最大边的最小值:u->v d[v] = min(d[i],max(d[u],g[u][v])) 即通过u -> v的所有路径的,和k -> v(k != u)的所有路径中,最大边取小的那个
-
遇到的问题:
//方法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;}