codeforces 987 D. Fair
2 seconds
512 megabytes
standard input
standard output
Some company is going to hold a fair in Byteland. There are $$$n$$$ towns in Byteland and $$$m$$$ two-way roads between towns. Of course, you can reach any town from any other town using roads.
There are $$$k$$$ types of goods produced in Byteland and every town produces only one type. To hold a fair you have to bring at least $$$s$$$ different types of goods. It costs $$$d(u,v)$$$ coins to bring goods from town $$$u$$$ to town $$$v$$$ where $$$d(u,v)$$$ is the length of the shortest path from $$$u$$$ to $$$v$$$. Length of a path is the number of roads in this path.
The organizers will cover all travel expenses but they can choose the towns to bring goods from. Now they want to calculate minimum expenses to hold a fair in each of $$$n$$$ towns.
There are $$$4$$$ integers $$$n$$$, $$$m$$$, $$$k$$$, $$$s$$$ in the first line of input ($$$1 \le n \le 10^{5}$$$, $$$0 \le m \le 10^{5}$$$, $$$1 \le s \le k \le min(n, 100)$$$) — the number of towns, the number of roads, the number of different types of goods, the number of different types of goods necessary to hold a fair.
In the next line there are $$$n$$$ integers $$$a_1, a_2, \ldots, a_n$$$ ($$$1 \le a_{i} \le k$$$), where $$$a_i$$$ is the type of goods produced in the $$$i$$$-th town. It is guaranteed that all integers between $$$1$$$ and $$$k$$$ occur at least once among integers $$$a_{i}$$$.
In the next $$$m$$$ lines roads are described. Each road is described by two integers $$$u$$$ $$$v$$$ ($$$1 \le u, v \le n$$$, $$$u \ne v$$$) — the towns connected by this road. It is guaranteed that there is no more than one road between every two towns. It is guaranteed that you can go from any town to any other town via roads.
Print $$$n$$$ numbers, the $$$i$$$-th of them is the minimum number of coins you need to spend on travel expenses to hold a fair in town $$$i$$$. Separate numbers with spaces.
5 5 4 3
1 2 4 3 2
1 2
2 3
3 4
4 1
4 5
2 2 2 2 3
7 6 3 2
1 2 3 3 2 2 1
1 2
2 3
3 4
2 5
5 6
6 7
1 1 1 2 2 1 1
Let's look at the first sample.
To hold a fair in town $$$1$$$ you can bring goods from towns $$$1$$$ ($$$0$$$ coins), $$$2$$$ ($$$1$$$ coin) and $$$4$$$ ($$$1$$$ coin). Total numbers of coins is $$$2$$$.
Town $$$2$$$: Goods from towns $$$2$$$ ($$$0$$$), $$$1$$$ ($$$1$$$), $$$3$$$ ($$$1$$$). Sum equals $$$2$$$.
Town $$$3$$$: Goods from towns $$$3$$$ ($$$0$$$), $$$2$$$ ($$$1$$$), $$$4$$$ ($$$1$$$). Sum equals $$$2$$$.
Town $$$4$$$: Goods from towns $$$4$$$ ($$$0$$$), $$$1$$$ ($$$1$$$), $$$5$$$ ($$$1$$$). Sum equals $$$2$$$.
Town $$$5$$$: Goods from towns $$$5$$$ ($$$0$$$), $$$4$$$ ($$$1$$$), $$$3$$$ ($$$2$$$). Sum equals $$$3$$$.
【题意】
$$$n$$$个结点,$$$m$$$条边,$$$s$$$种商品,每个结点含有一种商品,且保证所有商品至少被一个结点包含。对于每个结点,选择至少$$$k$$$个结点,使他们包含至少$$$k$$$种商品,且到该结点的总距离和最小。
【思路】
结点和边的数量为1e5,而商品个数只有100,如果从每个结点出发直到寻找$$$k$$$个商品为止,那么这样做其实并不划算,其原因在于很难决定最近的商品在哪条路上,需要搜索到很深的地方,而且含有相同商品的城市会被反复访问。为了节约时间,可以预先从商品出发进行bfs,那么经过的城市都是最近的,这样处理以后每个城市就知道,自己到每个商品的最近距离,要凑齐$$$k$$$个商品只需要选择前k个最小的距离就行了。
【注意】
这里的bfs需要抽象理解一下,假如对$$$i$$$号商品进行bfs,那么第一步就要直接转移到所有含$$$i$$$的城市,然后就是平常的bfs了,每次扩展1个距离,遍历完所有城市后,每个城市就都有一个获得$$$i$$$的最短距离了。
【代码】
#include<stdio.h>
#include<queue>
#include<memory.h>
#include<algorithm>
#include<vector> using std::queue;
using std::vector;
using std::sort; vector<int> t[];
#define N 100005
vector<int>node[N];
int cost[N][] = { };
int vis[N];
void bfs(int si) {
queue<int>help; int sz = t[si].size();
//将含si的所有城市加入到bfs的第一次转移
for (int i = ; i < sz; ++i) {
int next=t[si][i];
help.push(next);
vis[next] = ;
}
//bfs继续转移
for (int cnt = ; !help.empty();cnt++) {
int sz = help.size();
for (int i = ; i < sz; ++i) {
int next = help.front(); help.pop();
int nsz = node[next].size();
for (int t = ; t < nsz; ++t) {
int pnext = node[next][t];
if (vis[pnext] == )continue;
vis[pnext] = ;
cost[pnext][si] = cnt;
help.push(pnext);
}
}
}
} int main() {
int n, m, s, k;
scanf("%d %d %d %d", &n, &m, &s, &k);
int a0,a1;
for (int i = ; i <= n; ++i) {
scanf("%d", &a0);
t[a0].push_back(i);
}
for (int i = ; i < m; ++i) {
scanf("%d %d", &a0, &a1);
node[a0].push_back(a1);
node[a1].push_back(a0);
}
for (int i = ; i <= s; ++i) {
memset(vis, , sizeof vis);
bfs(i);
}
for (int i = ; i <= n; ++i) {
//排序并选择前k个
sort(cost[i] + , cost[i] + + s);
int sum = ;
for (int t = ; t <= k; ++t)
sum += cost[i][t];
printf("%d ", sum);
}
}
codeforces 987 D. Fair的更多相关文章
- codeforces 897A Scarborough Fair 暴力签到
codeforces 897A Scarborough Fair 题目链接: http://codeforces.com/problemset/problem/897/A 思路: 暴力大法好 代码: ...
- CF 987 D. Fair
D. Fair http://codeforces.com/contest/987/problem/D 题意: n个城镇m条道路,(保证没有重边,两个城镇间可以到达),每个城镇拥有的特产ai(可能多个 ...
- [Codeforces Round 486A] Fair
[题目链接] https://codeforces.com/contest/986/problem/A [算法] 用dist(i,j)表示第i种食物运到第j个城市需要的最小代价 将所有特产为第i中食物 ...
- CodeForces 1084D The Fair Nut and the Best Path
The Fair Nut and the Best Path 题意:求路径上的 点权和 - 边权和 最大, 然后不能存在某个点为负数. 题解: dfs一遍, 求所有儿子走到这个点的最大值和次大值. 我 ...
- CodeForces - 1073D Berland Fair
XXI Berland Annual Fair is coming really soon! Traditionally fair consists of nnbooths, arranged in ...
- Codeforces 987 K预处理BFS 3n,7n+1随机结论题/不动点逆序对 X&Y=0连边DFS求连通块数目
A /*Huyyt*/ #include<bits/stdc++.h> #define mem(a,b) memset(a,b,sizeof(a)) #define pb push_bac ...
- Codeforces 1083E The Fair Nut and Rectangles
Description 有\(N\)个左下定点为原点的矩阵, 每个矩阵\((x_i,~y_i)\)都有一个数\(a_i\)表示其花费. 没有一个矩阵包含另一个矩阵. 现要你选出若干个矩阵, 使得矩阵组 ...
- Codeforces 1083B The Fair Nut and Strings
Description 给定两个由 \('a'\), \('b'\) 组成的字符串 \(a\), \(b\),以及两个整数 \(n\) 和 \(k\) \(n\) 表示字符串 \(a\),\(b\) ...
- Codeforces 987 F - AND Graph
F - AND Graph 思路: 首先,x & (~x) == 0 其次,~x 的 子集 y = ((~x) ^ (1<<k)), 0<= k < n(如果k这一位是 ...
随机推荐
- C++的特点
C和C++ C主要是应用在在驱动层,是面向过程的编程语言,对类型的定义不是很严格.C++主要是应用与应用层,是C语言的一个加强版,可以完全兼容C语言,并且还有很多C语言不具备的特性,如,C++是一种面 ...
- POJ2505 A multiplication game(博弈)
题意 开始时$p = 1$,每次可以乘$2 - 9$,第一个使得$p \geqslant n$的人赢 问先手是否必胜 $1 <n <4294967295$ Sol 认真的推理一波. 若当前 ...
- 北京Uber优步司机奖励政策(3月4日)
滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...
- SDWebImage的原理 和 实现机制 --- tableView 滑动卡的问题
一.原理 1)当我门需要获取网络图片的时候,我们首先需要的便是URl没有URl什么都没有,获得URL后我们SDWebImage实现的并不是直接去请求网路,而是检查图片缓存中有没有和URl相关的图片,如 ...
- day 2 飞机大战原理
1. 程序的图片的坐标 (左上角为顶点) 2.图片变成动态的 3.集成显卡 和独立显卡
- SpringBoot入门(一)——开箱即用
本文来自网易云社区 Spring Boot是什么 从根本上来讲Spring Boot就是一些库的集合,是一个基于"约定优于配置"的原则,快速搭建应用的框架.本质上依然Spring, ...
- MAC 更新brew 镜像源
mac 更新brew镜像源 cd "$(brew --repo)/Library/Taps/homebrew/homebrew-core" git remote set-url o ...
- android 学习十四 探索安全性和权限
1.部署安全性:应用程序必须使用数字证书才能安装到设备上. 2.执行期间的安全性: 2.1 使用独立进程 2.2 使用固定唯一用户ID 2.3 申明性权限模型 3数字证书 ...
- uvaoj1339 - Ancient Cipher(思维题,排序,字符串加密)
https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...
- DNA序列 (DNA Consensus String,ACM/ICPC Seoul 2006,UVa1368
题目描述:算法竞赛入门经典习题3-7 题目思路:每列出现最多的距离即最短 #include <stdio.h> #include <string.h> int main(int ...