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这一位是 ...
随机推荐
- 对于微信小程序登录的理解图
有两种获取用户信息的方案. 1.不包含敏感信息openId 的json对象(包含:nickname.avatarUrl等基本信息) 2.包含敏感信息openId的基本信息. 第一种获取方案 1.首先调 ...
- CRL2.1更新
增加没有主键ID的抽象类,使能自义主键字段实现MODEL抽象类定义结构为 /// <summary> /// 基类,不包含任何字段 /// 如果有自定义主键名对象,请继承此类型 /// & ...
- C#新特性记录
C#6.0新特性笔记 Getter专属赋值 可以在构造函数中,给只有get的属性赋初始值. class Point { public int x { get; } public Point() { x ...
- tpo-09 C2 Return a sociology book
check out 在library里有借书的意思 第 1 段 1.Listen to a conversation between a student and a librarian employe ...
- Siki_Unity_2-10_数据结构与算法
Unity 2-10 数据结构与算法 任务1-1:数据结构简介 数据结构:数据存储的结构,数据之间的关系 数据结构分类: 集合:同属于一个集合 线性结构:数据元素存在一对一的关系 树形结构:数据元素存 ...
- mysql 各种存储引擎的特点
- 376. Binary Tree Path Sum【LintCode java】
Description Given a binary tree, find all paths that sum of the nodes in the path equals to a given ...
- (python)leetcode刷题笔记04 Median of Two Sorted Arrays
4. Median of Two Sorted Arrays There are two sorted arrays nums1 and nums2 of size m and n respectiv ...
- ionic typescript--验证码发送倒计时功能
1.新建页面 ionic g page forget 2.mode.html文件 <ion-item> <ion-input clearInput [(ngModel)]='co ...
- python常用命令—‘\r’
# \r 默认表示将输出的内容返回到第一个指针,这样的话,后面的内容会覆盖前面的内容 如常用的显示程序完成进度!!