UVA - 10099 The Tourist Guide (floyd+dp)

题目大意:
有一个导游,要带领团队从当前点,走到目标点,但是每条路一次性通过的人有数量限制,所以需要分批次进行。问最少需要分多少次进行。
那么每次可以运输的人数由当前路程,最小的可以通过的人数决定。

注意:题目有说,每次导游要占用巴士的一个位置。
那么 运行次数 = ceil(总人数 / (当前运输最多人数-1) );

解析:最短路问题的改编。
求最小边的最大值的方程为:
d[i][j]=max{d[i][j],min{d[i][k],d[k][j]}}

初始化:所有 d[i][j]=0;

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
const int N = 105;
const int INF = 0x3f3f3f3f;
int n,m;
int d[N][N];
int start,end,men;
void init() {
	memset(d,0,sizeof(d));
}
void floyd() {
	for(int k = 1; k <= n; k++) {
		for(int i = 1; i <= n; i++) {
			for(int j = 1; j <= n; j++) {
				d[i][j] = max( d[i][j], min(d[i][k],d[k][j]) );
			}
		}
	}
}
int main() {
	int x,y,val;
	int cas = 1;
	while(scanf("%d%d",&n,&m) != EOF && (n || m)) {
		init();
		for(int i = 0; i < m; i++) {
			scanf("%d%d%d",&x,&y,&val);
			d[x][y] = d[y][x] = val;
		}
		floyd();
		scanf("%d%d%d",&start,&end,&men);
		double ans = men / (double)(d[start][end] - 1);
		printf("Scenario #%d\n",cas++);
		printf("Minimum Number of Trips = %d\n\n",(int)ceil(ans));			
	}
	return 0;
}


你可能感兴趣的:(uva,guide,the,10099,Tourist)