城市交通费

时间:2019-06-12
本文章向大家介绍城市交通费,主要包括城市交通费使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

城市交通费
【问题描述】
有 n 个城市, 编号 1~n。 其中 i 号城市的繁华度为 pi。 省内有 m 条可以双向同行的高速
公路, 编号 1~m。 编号为 j 的高速公路连接编号为 aj 和 bj 两个城市, 经过高速公路的费用
是 wj。 若从城市 x 出发到某城市 y, 除了需要缴纳高速公路费用, 还要缴纳“城市建设费”
(为从 x 城市到 y 城市所经过的所有城市中繁华度的最大值, 包括 x 和 y 在内) 。
现提出 q 个询问, 每个询问给出一组 x 和 y, 你需要回答从 x 出发到 y 城市, 所需要的
最低交通费(高速公路费+城市建设费) 是多少。
【输入】
第一行三个整数 n,m,q。
第二行 n 个整数, 表示 p1~pn。
接下来 m 行中, 每行 3 个正整数, 第 j 行包含 Aj, Bj, Wj。
随后 Q 行每组两个正整数 x, y 表示一组询问。
【输出】
共 Q 行, 为对 Q 个问题的回答: x 城市到 y 城市的最小交通费用。
【样例输入】
5 7 2
2 5 3 3 4
1 2 3
1 3 2
2 5 3
5 3 1
5 4 1
2 4 3
3 4 4
1 4
2 3
【样例输出】
8 9
【数据范围及约定】
n≤250, m≤20000, Q≤10000, Pi≤10000, Wj≤2000, 保证任意两个城市可以互相到达。
【样例说明】
图中, 代表城市的格子中第一个数字是城市编号, 第二个红色数字是该城市的繁华度。
(1) 从城市 1 到城市 4 的最小交通费用路线是: 1 3 5 4; 公路费是 2+1+1=4; 城市建设费是
max{2,3,4,3}=4; 总交通费用 4+4=8。
(2) 从城市 2 到城市 3 的最小交通费用路线是: 2 5 3; 公路费是 3+1=4; 城市建设费是
max{5,4,3}=5; 总交通费用 4+5=9。

由于这个题是多组询问,显然要用floyd做,但关键是如何处理繁华度这个东西,因为最短路径和最小繁华度的路径很有可能不是一条路

我们可以考虑对繁华度进行排序,并记录下来排序之后每个点对应的编号(我也不知道why)

代码:

#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
#include<algorithm>
using namespace std;
int n,m,q,p[300],aj,bj,wj,x,y,f[300][300],a[300][300],top,t[300];
int cmp(int x,int y)
{
    return p[x]<p[y];
}
int main()
{
    //freopen("road.in","r",stdin);
    //freopen("road.out","w",stdout);
    memset(a,63,sizeof(a));
    top=0;
    scanf("%d%d%d",&n,&m,&q);
    for(int i=1;i<=n;i++)
        scanf("%d",&p[i]);
    for(int i=1;i<=m;i++)
    {
        scanf("%d%d%d",&aj,&bj,&wj);
        a[aj][bj]=min(a[aj][bj],wj);
        a[bj][aj]=min(a[bj][aj],wj);
    }
    //邻接矩阵存图 
    for(int i=1;i<=n;i++)
    {
        a[i][i]=0;//自己到自己的距离为0 
        t[i]=i;//节点的标号 
    }
    sort(t+1,t+1+n,cmp);//按照繁华度排序 
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
            f[i][j]=a[i][j]+max(p[i],p[j]);
    //初始化 
    for(int k=1;k<=n;k++)//floyd枚举中间点 
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
            {
                a[i][j]=min(a[i][j],a[i][t[k]]+a[t[k]][j]);//松弛两个点之间的最短路 
                f[i][j]=min(f[i][j],a[i][j]+max(p[i],max(p[j],p[t[k]])));//最小花费 
            }
    for(int i=1;i<=q;i++)
    {
        scanf("%d%d",&x,&y);
        printf("%d\n",f[x][y]);
    }
    //fclose(stdin);
    //fclose(stdout);
    return 0;
     
}

原文地址:https://www.cnblogs.com/lcezych/p/11010002.html