题目大意:给一张无向图,边权为正整数,代表两端点之间路上能承载的最大重量,给定一个起点和一个终点,问起点到终点最大载货量。
题目分析:此题方法很多。floyd比较好想。每条路都有最大承载重量,所以经过这条路的车重量不能超过这个数,所以要求起点到终点所以路径中既能保证通过所有路,又要保证运货量最大。点的数量不超过200,所以可以直接floyd,通过枚举任意2点之间所有路径,取最大值。那么此题的方程为:
weight[i][j] = max(weight[i][j],min(weight[i][k],weight[k][j]))。
其中min(weight[i][k],weight[k][j])是为了保证车能顺利从i到k,再从k到j,最后取最大值。
通过和这题的比较可以发现,floyd绝不是简单的3重循环,对里面的式子做些变形,floyd也可以灵活变通,达到比较好的效果。
详情请见代码:
#include <iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 205;
const int M = 20005;
const int INF = 0x3f3f3f3f;
int weight[N][N];
char city[N][33];
int m,n,num;
char str[33];
int st,ed;
int getid()
{
int i;
for(i = 1;i < num;i ++)
if(strcmp(str,city[i]) == 0)
return i;
return i;
}
void Floyd()
{
int i,j,k;
for(k = 1;k <= n;k ++)
for(i = 1;i <= n;i ++)
for(j = 1;j <= n;j ++)
weight[i][j] = max(weight[i][j],min(weight[i][k],weight[k][j]));
}
int main()
{
//freopen("data.in","r",stdin);
int i,a,b;
int cas = 0;
while(scanf("%d%d",&n,&m),(n + m))
{
num = 1;
memset(weight,0,sizeof(weight));
for(i = 1;i <= m;i ++)
{
scanf("%s",str);
a = getid();
if(a == num)
strcpy(city[num],str),num++;
scanf("%s",str);
b = getid();
if(b == num)
strcpy(city[num],str),num++;
scanf("%d",&weight[a][b]);
weight[b][a] = weight[a][b];
}
scanf("%s",str);
st = getid();
scanf("%s",str);
ed = getid();
printf("Scenario #%d\n",++cas);
Floyd();
printf("%d tons\n\n",weight[st][ed]);
}
return 0;
}
//288K 32MS