CodeForces 986A Fair

题目大意

题目链接
每个城市都可以生产一种物品,要选择一个城市举办party,要求举办party的城市至少有s 种不同的商品,因此需要从其他城市将商品运送到举办party的城市。
问若每个城市举办party运送的距离是多少?

题解

bfs+思维
枚举每种商品,求出每个城市获取到每种商品的最短距离,对于每个城市而言,将每种商品按照获取所需最短距离从小到大排序,前s个距离之和即为此城市的最小花费(无需知道取的哪几种商品)
—————————————
看懂代码后再看下面:
本质上,我们每次都是将生产某一种商品的城市全部入队,更新其他城市获取到其所生产的商品的最短距离。因此每一次“将生产某一种商品的城市全部入队”进行bfs都是在对每座城市获取到此类商品的最短距离进行更新。

代码

#include<bits/stdc++.h>
using namespace std;
const int N = 1e5+10;

int dis[N][105], kind[N], vis[N];
int idx, e[N<<1], ne[N<<1], h[N];
int n, m, k, s, a, b;

void add(int a, int b) {
	e[idx] = b, ne[idx] = h[a], h[a] = idx++;
}

int main() {
	memset(h, -1, sizeof h);
	cin>>n>>m>>k>>s;
	for(int i = 1;i <= n;i ++) cin>>kind[i];
	while(m--) cin>>a>>b, add(a, b), add(b, a);
	
	queue<int> q;
	
	for(int i = 1;i <= k;i ++) { // 枚举每种商品
		memset(vis, 0, sizeof vis);
		for(int j = 1;j <= n;j ++) 
			if(kind[j] == i)  // 将所生产的商品种类为i的城市先全部入队,以此扩展
				q.push(j), dis[j][i] = 0, vis[j] = 1; // dis(j,i)表示第j个城市获取到第i种商品的最短距离
		while(!q.empty()) {
			int t = q.front();
			q.pop();
			for(int j = h[t];j != -1;j = ne[j]) {
				int des = e[j];
				if(vis[des]) continue;
				dis[des][i] = dis[t][i] + 1;
				vis[des] = 1;
				q.push(des);
			}
		} 
	}
	
	for(int i = 1;i <= n;i ++) {
		int ans = 0;
		sort(dis[i]+1, dis[i]+k+1);
		for(int j = 1;j <= s;j ++)
			ans += dis[i][j];
		cout<<ans<<' ';
	}
} 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不牌不改

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值