城市交通费

2017青岛比赛第二题(亦或是最后一题?记不真切了),后天就青岛2018了。。。然而今天才会去年的题。。。

题目大意

有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
l第二行:P1~Pn
接下来 m 行,每行3个正整数,第 j 行包含 Aj , Bj ,Wj
随后 Q 行每组二个正整数 X,Y,表示一组询问
n<=250,m<=2e4,Q<=1e4,Pi<=1e4,Wj<=2e3,保证任意两个城市可以互相到达

输出格式:

Q行,每行对应一个整数,即对应询问的答案

分析:此题乍一看似乎是 Floyd 算法的应用,但实际上用 Dijkstra 更好,可以将 “当前节点” 与 “标记节点” 捆绑起来。(但并不是说 Floyd 不能做,只是较麻烦,详见 能神带你飞 博客:https://www.cnblogs.com/nengshen/)

 1 //Copyright(C)昤昽
 2 //2018.05.20
 3 #include <cstdio>
 4 #include <cstring>
 5 #include <iostream>
 6 using namespace std;
 7 const int N=250+1,inf=(1<<30)-1;
 8 int g[N][N],v[N],pp[N][N],p[N],dist[N][N];//,sd[N];
 9 void dijkstra(int begin,int n)
10 {
11     memset(v,0,sizeof(v));
12     int (&d)[N]=dist[begin],(&boom)[N]=pp[begin];
13     for(int i=1;i<=n;i++)d[i]=inf;d[begin]=0;
14     for(int i=1;i<=n;i++)boom[i]=0;boom[begin]=p[begin];
15     for(int i=1;i<=n;i++)
16     {
17         int x,m=inf;
18         for(int y=1;y<=n;y++)if(!v[y] && d[y]+boom[y]<=m)m=d[x=y]+boom[y];
19         v[x]=1;
20         for(int y=1;y<=n;y++)
21             if(g[x][y] && d[x]+g[x][y]+max(boom[x],p[y]) < d[y]+boom[y])
22             {
23                 d[y]=d[x]+g[x][y];
24                 boom[y]=max(boom[x],p[y]);
25             }
26     }
27 }
28 int main()
29 {
30 //    freopen("cityFee.in","r",stdin);
31 //    freopen("cityFee.out","w",stdout);
32     memset(g,0,sizeof(g));
33     memset(p,0,sizeof(p));
34     memset(pp,0,sizeof(pp));
35     int n,m,Q;
36     scanf("%d %d %d",&n,&m,&Q);
37     for(int i=1;i<=n;i++)scanf("%d",&p[i]);
38     for(int i=1;i<=m;i++)
39     {
40         int a,b,d;
41         scanf("%d %d %d",&a,&b,&d);
42         g[a][b]=g[b][a]=d;
43     }
44     for(int i=1;i<=n;i++)dijkstra(i,n);
45     for(int i=1;i<=Q;i++)
46     {
47         int x,y;
48         scanf("%d %d",&x,&y);
49         printf("%d",dist[x][y]+pp[x][y]);
50         if(i!=Q)printf("\n");
51     }
52     return 0;
53 }

猜你喜欢

转载自www.cnblogs.com/zhinv/p/9063891.html