城市交通费

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 }

 

 1 #include <queue>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <iostream>
 5 using namespace std;
 6 const int N=250+1,inf=(1<<30)-1;
 7 int head[N],p[N],dist[N][N],pp[N][N],cnt=0;
 8 bool have_searched[N],inq[N];
 9 queue<int>q;
10 struct Edge{
11     int to,d,link;
12     Edge(){to=0;d=inf;link=-1;}
13 }e[N<<1];
14 void insert(int from,int to,int dis)
15 {
16     cnt++;
17     e[cnt].link=head[from];head[from]=cnt;
18     e[cnt].to=to;e[cnt].d=dis;
19 }
20 void spfa(int begin,int n)
21 {
22     if(have_searched[begin])return;
23     have_searched[begin]=true;
24     
25     memset(inq,0,sizeof(inq));
26     while(!q.empty())q.pop();
27     
28     int (&dis)[N]=dist[begin],(&boom)[N]=pp[begin];
29     for(int i=1;i<=n;i++)dis[i]=inf;dis[begin]=0;
30     
31     q.push(begin);inq[begin]=true;
32     while(!q.empty())
33     {
34         int x=q.front();q.pop();
35         inq[x]=false;
36         for(int it=head[x];e[it].link!=-1;it=e[it].link)
37         {
38             int y=e[it].to;
39             if(dis[x]+e[it].d+max(boom[x],p[y]) < dis[y]+boom[y])
40             {
41                 dis[y]=dis[x]+e[it].d;
42                 boom[y]=max(boom[x],p[y]);
43                 if(!inq[y]){q.push(y);inq[y]=true;}
44             }
45         }
46     }
47 }
48 int main()
49 {
50     memset(pp,0,sizeof(pp));
51     memset(head,-1,sizeof(head));
52     memset(have_searched,0,sizeof(have_searched));
53 
54     int n,m,Q;
55     scanf("%d %d %d",&n,&m,&Q);
56     for(int i=1;i<=n;i++)scanf("%d",&pp[i][i]);
57     for(int i=1;i<=m;i++)
58     {
59         int a,b,w;
60         scanf("%d %d %d",&a,&b,&w);
61         insert(a,b,w);insert(b,a,w);
62     }
63     for(int i=1;i<=Q;i++)
64     {
65         int x,y;
66         scanf("%d %d",&x,&y);
67         spfa(x,n);
68         printf("%d",dist[x][y]+pp[x][y]);
69         if(i!=Q)printf("\n");
70     }
71     return 0;
72 }

 

posted @ 2018-05-20 17:09  昤昽  阅读(276)  评论(0编辑  收藏  举报