思路:建图后,本题求的是在所有从顶点1到顶点2的路径中,使得路径上最大边的权值,最小,求出该权值
容易想多用kurscal算法
注意输出:c++交时,输出用%lf。g++则用%f
#include
#include
#include
#include
#include
#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
#include
#include
#include
#include
#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;
}