CF 986A Fair(多源BFS)
题目描述
一些公司将在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 }