CF 986A Fair(多源BFS)

本文介绍了一种解决商品交易会物流成本问题的算法。在一个由多个城市组成的网络中,每种商品仅在一个城市生产,目标是计算在满足商品种类需求下,各城市作为举办地的最低物流成本。算法通过BFS遍历,计算每种商品到所有城市的最短路径,再累加求得最低总成本。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目描述

一些公司将在Byteland举办商品交易会(or博览会?)。在Byteland有 nnn 个城市,城市间有 mmm 条双向道路。当然,城镇之间两两连通。 Byteland生产的货物有 kkk 种类型,每个城镇只生产一种。 为了举办商品交易会,你必须至少带来 sss 种不同类型的商品。将货物从 uuu 镇带到城镇 vvv 将花费 d(u,v)d(u,v)d(u,v) 的费用,其中 d(u,v)d(u,v)d(u,v) 是从 uuu 到 vvv 的最短路径的长度。 路径的长度是这个路径中的道路的数量。 组织者将支付所有的运输费用,但他们可以选择从哪些城镇带来货物。现在他们想计算每个城镇举办商品交易会的最小费用。

题解

我们考虑每种货物分开做。把生产同一种货物的城市扔到队列里跑BFS,得到每一种货物到每个点的最短距离。

 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 #include<cmath>
 5 #include<algorithm>
 6 #include<queue>
 7 using namespace std;
 8 const int N=100010;
 9 const int K=200;
10 int n,m,k,s,c[N],vis[N][K],head[N],cnt,ans;
11 queue<int> q; 
12 struct edge{
13     int to,nxt;
14 }e[N*3];
15 void add(int u,int v){
16     cnt++;
17     e[cnt].nxt=head[u];
18     e[cnt].to=v;
19     head[u]=cnt;
20 }
21 int main(){
22     scanf("%d%d%d%d",&n,&m,&k,&s);
23     for(int i=1;i<=n;i++){
24         scanf("%d",&c[i]); 
25     }
26     for(int i=1,u,v;i<=m;i++){
27         scanf("%d%d",&u,&v);
28         add(u,v);
29         add(v,u);
30     }
31     memset(vis,-1,sizeof(vis));
32     for(int i=1;i<=k;i++){
33         for(int j=1;j<=n;j++){
34             if(c[j]==i)q.push(j),vis[j][i]=0;
35         }
36         while(!q.empty()){
37             int u=q.front();
38             q.pop();
39             for(int x=head[u];x;x=e[x].nxt){
40                 int v=e[x].to;
41                 if(vis[v][i]>-1)continue;
42                 vis[v][i]=vis[u][i]+1;
43                 q.push(v);
44             }
45         }
46     }
47     for(int i=1;i<=n;i++){
48         ans=0;
49         sort(vis[i]+1,vis[i]+1+k);
50         for(int j=1;j<=s;j++){
51             ans+=vis[i][j];
52         }
53         printf("%d ",ans);
54     }
55     return 0;
56 }
View Code

 

转载于:https://www.cnblogs.com/Xu-daxia/p/9380719.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值