Live2D
博客园 首页 私信博主 显示目录 隐藏目录 管理 动画

6.12考试 T3 城市交通费

城市交通费

【问题描述】有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城市的最小交通费用。

输入样例1:

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

输出样例1:

8
9

该题其他输入输出数据:https://share.weiyun.com/5R3eFO1

思路:

Floyd,由于Floyd在寻找最短路时会更新之前的路径,所以无法单独建立一个数组记录从i到j的最大城市建设费。在更新map[]的同时更新cost_m[];

解析:

t[]数组表示城市建设费的升序排列;

map[]表示当前最小的路费;

cost_m[]表示当前的最小(路费+最大城市建设费);

代码:

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>

using namespace std;

int n,m,q;
int cost[258],t[258],cost_m[258][258];
int map[258][258];

long long read()
{
    long long x=0,f=1;
    char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}

int cmp(int x,int y)
{
    return cost[x]<cost[y];
}

int main()
{    
    freopen("road.in","r",stdin);
    freopen("road.out","w",stdout);
    n=read();m=read();q=read();
    for(int i=1;i<=n;++i)
        for(int j=1;j<=n;++j)
            map[i][j]=999999999;
    for(int i=1;i<=n;++i) cost[i]=read();
    for(int i=1;i<=m;++i)
    {
        int a,b,w;
        a=read();b=read();w=read();
        map[a][b]=min(map[a][b],w);
        map[b][a]=min(map[b][a],w);
    }
    for(int i=1;i<=n;++i)
    {
        map[i][i]=0;
        t[i]=i;
    }
    sort(t+1,t+n+1,cmp);//表示cost[]的升序 ,如果不sort会WA掉,因为是最小花费,所以我们用最小的城市建设费作为重中点来更新其他点 
    for(int i=1;i<=n;++i)
        for(int j=1;j<=n;++j)
            cost_m[i][j]=map[i][j]+max(cost[i],cost[j]);//预处理cost_m 
    for(int k=1;k<=n;++k)//中点要放在外面 
        for(int i=1;i<=n;++i)
            for(int j=1;j<=n;++j)
            {
                map[i][j]=min(map[i][j],map[i][t[k]]+map[t[k]][j]);//更新当前的路费 
                cost_m[i][j]=min(cost_m[i][j],map[i][j]+max(cost[i],max(cost[j],cost[t[k]])));//更新当前的总费用 
            }
    for(int i=1;i<=q;++i)
    {
        int u,v;
        u=read();v=read();
        printf("%d\n",cost_m[u][v]);
    }
    return 0;
}

 

posted @ 2019-06-12 16:48  _hhs  阅读(315)  评论(0)    收藏  举报