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 }
View Code

 

posted @ 2018-07-28 09:31  Xu-daxia  阅读(202)  评论(0编辑  收藏  举报