思路:建图后,本题求的是在所有从顶点1到顶点2的路径中,使得路径上最大边的权值,最小,求出该权值 容易想多用kurscal算法
注意输出:c++交时,输出用%lf。g++则用%f
#include <cstdio> #include <cstring> #include <algorithm> #include <cstdlib> #include <cmath> #define N 205 using namespace std; const double inf = 999999999.0; typedef struct note { int x; int y; }point; typedef struct node { int u; int v; double w; }edge; int n,f[N]; point a[N]; edge e[N*N]; double minjump; void init() { for (int i = 1; i <= n; i++) f[i] = i; } int find(int x)//找父节点 { if (f[x] == x) return x; else return f[x] = find(f[x]); } int merge(int x, int y) { int t1, t2; t1 = find(x); t2 = find(y); if (t1 != t2)//根不一样 { f[t2] = t1; return 1; } return 0; } int same(int x, int y) { return find(x) == find(y); } int cmp(edge a, edge b) { return a.w < b.w; } int main() { int cas = 0, vis[N]; while (scanf("%d", &n) != EOF && n) { int cnt = 0; minjump = 0; memset(vis, 0, sizeof(vis)); for (int i = 1; i <= n; i++) scanf("%d%d", &a[i].x, &a[i].y); //存储边 for (int i = 1; i <= n; i++) { for (int j = i + 1; j <= n; j++) { e[cnt].u = i; e[cnt].v = j; e[cnt].w = sqrt(pow(a[i].x - a[j].x, 2) + pow(a[i].y - a[j].y, 2)); cnt++; } } int m = cnt;//m条边 sort(e, e + m, cmp); init();//初始化集合 cnt = 0; for (int i = 0; i < m; i++) { if (merge(e[i].u, e[i].v)) { if (minjump < e[i].w) minjump = e[i].w; } if (same(1,2)) break;//当1,2位于同一集合时,说明已找到生成树 } if (cas) printf("\n"); printf("Scenario #%d\n", ++cas); printf("Frog Distance = %.3lf\n", minjump); } return 0; }方法2:迪杰斯特拉变式,或者floyd也行
把松弛的方程改为dis[i] = min(dis[i], max(dis[k], map[k][i]));
#include <cstdio> #include <cstring> #include <cstdlib> #include <algorithm> #include <cmath> #define N 205 #define INF 99999999 using namespace std; typedef struct node { int x; int y; }point; point note[N]; int n; double map[N][N]; double dis[N]; int vis[N]; double distance(point a, point b) { return sqrt(pow(a.x - b.x, 2) + pow(a.y - b.y, 2)); } void dijkstra() { memset(vis, 0, sizeof(vis)); vis[1] = 1;//标记第一个点 dis[1] = 0; for (int i = 2; i <= n; i++) dis[i] = INF; for (int i = 1; i <= n; i++) dis[i] = map[1][i]; for (int i = 1; i <= n-1; i++)//循环n-1次 { /*找出离起点最近的点*/ double minn = INF; int k = -1; for (int j = 1; j <= n; j++) { if (!vis[j] && dis[j] < minn) { minn = dis[j]; k = j; } } vis[k] = 1; for (int i = 1; i <= n; i++)//松弛操作 { if (!vis[i]) dis[i] = min(dis[i], max(dis[k], map[k][i])); //dis的含义为起点到顶点i所有路径中最长边的最小值。 } } } int main() { int cnt = 0; while (scanf("%d", &n) != EOF && n) { //建图,起点为1,终点为2 for (int i = 1; i <= n; i++) scanf("%d%d", ¬e[i].x, ¬e[i].y); for (int i = 1; i <= n; i++) { for (int j = 1; j <= n; j++) { map[i][j] = map[j][i] = distance(note[i], note[j]); } } //迪杰斯特拉算法 dijkstra(); //输出 if (cnt) printf("\n"); printf("Scenario #%d\nFrog Distance = %.3lf\n",++cnt,dis[2]); } return 0; }