Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 28514 | Accepted: 9263 |
Description
Input
Output
Sample Input
2 0 0 3 4 3 17 4 19 4 18 5 0
Sample Output
Scenario #1 Frog Distance = 5.000 Scenario #2 Frog Distance = 1.414
题意:给出n个点的坐标,连通第一个点和第二个点有很多条路径,每条路径都会有 一个最大距离d - ->(当前路径经过的点集里面 任意两点间的距离都小于或者等于d)。题目要求找到这样的一个路径:(1)连通1,2两点;(2)这条路径中的最大距离d 是所有可选择路径中最小的。 输出这条路径的最大距离d。
枚举+并查集:16ms (还是这个思路好想) 按权值升序排列,从前到后枚举并判断1,2是否连通即可。
#include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #define INF 0x3f3f3f #define MAX 200+10 using namespace std; int n; int k = 1; int m; int set[MAX]; double x[MAX], y[MAX]; struct rec { int s, e; double d; }num[200*200+10]; bool cmp(rec a, rec b) { return a.d < b.d; } double dis(double x1, double y1, double x2, double y2) { return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)); } void init() { for(int i = 1; i <= n; i++) set[i] = i; } int find(int p) { int t; int child = p; while(p != set[p]) p =set[p]; while(child != p) { t = set[child]; set[child] = p; child = t; } return p; } void merge(int x, int y) { int fx = find(x); int fy = find(y); if(fx != fy) set[fx] = fy; } void getmap() { int i, j; m = 0; for(i = 1; i <= n; i++) scanf("%lf%lf", &x[i], &y[i]); for(i = 1; i <= n; i++) { for(j = i+1; j <= n; j++) { num[m].s = i; num[m].e = j; num[m++].d = dis(x[i], y[i], x[j], y[j]); } } sort(num, num+m, cmp); } void slove() { int i, j; int exist; double ans; for(i = 0; i < m; i++) { init();//初始化 ans = num[i].d; exist = 0; for(j = i; j < m; j++) { ans = num[j].d;//选择最大的 merge(num[j].s, num[j].e); if(find(1) == find(2)) { exist = 1;//连通 break; } } if(exist)//第一个满足的一定是最小的 { printf("Scenario #%d\nFrog Distance = %.3lf\n\n", k++, ans); return ; } } } int main() { while(scanf("%d", &n), n) { getmap();//建图 slove(); } return 0; }
最短路径变形:16ms 错了两次 醉了。。。
思路:dijkstra算法 更新环节dist[j] = min(dist[j], dist[next] + map[next][j])(更新最短距离,一个距离是源点到该点的!当前!最短距离 ,另一个是通过媒介点所得到的距离)。 按照题目要求,两个过程各自对应一个最大距离d,而我们要的是这两个最大距离里面的较小的值,即dist[j] = min(max(dist[next], map[next][j]),dist[j]).
#include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #define INF 0x3f3f3f #define MAX 200+10 using namespace std; double map[MAX][MAX], dist[MAX]; double x[MAX], y[MAX]; int vis[MAX]; int n, p = 1; double dis(double x1, double y1, double x2, double y2) { return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)); } void init() { for(int i = 1; i <= n; i++) { for(int j = 1; j <= n; j++) { if(i == j) map[i][j] = 0; else map[i][j] = INF; } } } void getmap() { int i, j; for(i = 1; i <= n; i++) scanf("%lf%lf", &x[i], &y[i]); for(i = 1; i <= n; i++) { for(j = i+1; j <= n; j++) { map[i][j] = map[j][i] = dis(x[i], y[i], x[j], y[j]); } } } void dijkstra() { int i, j, next; double Min; int t = 0; for(i = 1; i <= n; i++) { vis[i] = 0; dist[i] = map[1][i]; } vis[1] = 1; for(i = 2; i <= n; i++) { Min = INF; for(j = 1; j <= n; j++) { if(!vis[j] && Min > dist[j]) { Min = dist[j]; next = j; } } vis[next] = 1; for(j = 1; j <= n; j++) { if(!vis[j]) { dist[j] = min(max(map[next][j], dist[next]), dist[j]); } } } printf("Scenario #%d\nFrog Distance = %.3lf\n\n", p++, dist[2]); } int main() { while(scanf("%d", &n), n) { init();//初始化 getmap();//建图 dijkstra(); } return 0; }