POJ-2253___Frogger——路径中最小(大)值 + 最短路

题目链接:点我啊╭(╯^╰)╮

题目大意:

     n n 个点的坐标图,有两只青蛙分别在第一个点和第二个点,要计算从第一只青蛙到第二只青蛙里,所有路径中,一条路径里某一步的最大值,的最小值
    如有两条距离: 1 4 3 1—4—3 1 6 3 1—6—3 ,一条路径里某一步的最大值分别为 4 4 3 3 ,最小值为 4 4 ,则答案为 4 4

解题思路:

    最短路变异,考虑点的数量,则迪杰斯特拉即可解决

代码思路:

    注意,题目要求的并不是最短距离,而是一条路径里某一步的最大值,所以在加点的过程中,将该点所新加的距离取最大值,然后再取最小值即可
    除此之外还能有Floyd、SPFA、最小生成树等等

P S PS: 本题与 P O J 1797 POJ -1797 是兄弟题目,下面给出代码,注意:本题是取最小值, P O J 1797 POJ- 1797 是取最大值,初始化与松弛操作不同!!!

核心:灵活的运用Dijkstra的思想,运用松弛的操作来对路径上的长度做文章,同时注意是求最大值还是最小值

P O J 2253 POJ-2253:

#include<bits/stdc++.h>
using namespace std;
const int INF = 0x3F3F3F3F;
const int N = 205;
int cas, m, n, st, vis[N];
double dis[N], x[N], y[N], mp[N][N];

void init() {
	for (int i=1; i<=n; i++) {
		for (int j=1; j<=n; j++) {
			if (i == j)	mp[i][j] = 0;
			else mp[i][j] = INF;
		}
		dis[i]=INF;
	}
	memset(vis, 0, sizeof(vis));
}

void creatgraph() {
	for (int i=1; i<=n; i++)
		scanf("%lf%lf", &x[i], &y[i]);
		
	for(int i=1; i<=n; i++)
		for(int j=i+1; j<=n; j++)
			mp[i][j]=mp[j][i]=sqrt(double(x[i]-x[j])*(x[i]-x[j])+double(y[i]-y[j])*(y[i]-y[j]));
}

void dijkstra(int st) {
	for (int i=1; i<=n; i++)
		dis[i] = mp[st][i];
	vis[st] = 1;
	for (int i=1; i<=n-1; i++) {	//循环n-1次
		/*找出离起点最近的点*/
		int minn = INF, k = -1;
		for (int j=1; j<=n; j++) {
			if (!vis[j] && dis[j]<minn) {
				minn = dis[j];
				k = j;
			}
		}
		if(k==-1) break;
		vis[k] = 1;
		for (int j=1; j<=n; j++) 	//松弛操作
			dis[j] = min(dis[j], max(dis[k], mp[k][j]));
	}
}

int main() {
	while(scanf("%d", &n), n) { //n个顶点,m条边
		init();	//初始化地图
		creatgraph();	//建图
		dijkstra(1);
		printf("Scenario #%d\nFrog Distance = %.3f\n\n", ++cas, dis[2]);
	}
}

P O J 1797 POJ-1797:

#include<bits/stdc++.h>
using namespace std;
const int INF = 0x3F3F3F3F;
const int N = 1005;
int cas, t, m, n, st, vis[N];
int dis[N], mp[N][N];

void init() {
	for (int i=1; i<=n; i++) {
		for (int j=1; j<=n; j++) {
			if (i == j)	mp[i][j] = 0;
			else mp[i][j] = -INF;
		}
	}
	memset(vis, 0, sizeof(vis));
}

void creatgraph() {
	int t1, t2, t3;
	for (int i=0; i<m; i++) {
		scanf("%d%d%d", &t1, &t2, &t3);//两个顶点和权值
		mp[t1][t2] = t3;
		mp[t2][t1] = t3;
	}
}

void dijkstra(int st) {
	for (int i=1; i<=n; i++)
		dis[i] = mp[st][i];
	vis[st] = 1;
	for (int i=1; i<=n-1; i++) {	//循环n-1次
		/*找出离起点最近的点*/
		int maxx = -INF, k = -1;
		for (int j=1; j<=n; j++) {
			if (!vis[j] && dis[j]>maxx) {
				maxx = dis[j];
				k = j;
			}
		}
		if(k==-1) break;
		vis[k] = 1;
		for (int j=1; j<=n; j++) 	//松弛操作
			dis[j] = max(dis[j], min(dis[k], mp[k][j]));
	}
}

int main() {
	scanf("%d", &cas);
	while(cas--) { //n个顶点,m条边
		scanf("%d%d", &n, &m);
		init();	//初始化地图
		creatgraph();	//建图
		dijkstra(1);
		printf("Scenario #%d:\n%d\n\n", ++t, dis[n]);
	}
}

猜你喜欢

转载自blog.csdn.net/Scar_Halo/article/details/83280803