poj2263&zoj1952Heavy Cargo(floyd)

题目请戳这里

题目大意:给一张无向图,边权为正整数,代表两端点之间路上能承载的最大重量,给定一个起点和一个终点,问起点到终点最大载货量。

题目分析:此题方法很多。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


你可能感兴趣的:(图论,最短路)