[题目链接]
https://codeforces.com/contest/986/problem/A
[算法]
用dist(i,j)表示第i种食物运到第j个城市需要的最小代价
将所有特产为第i中食物的城市加入队列 , 进行广度优先搜索BFS
显然 , 对于每个城市 , 答案为到该城市代价前s小的食物代价和
时间复杂度 : O(k(m + n))
[代码]
#include<bits/stdc++.h> using namespace std; const int MAXN = 1e5 + 10; const int MAXK = 110; const int inf = 1e9; struct edge { int to , nxt; } e[MAXN << 1]; int n , m , k , s , tot; int value[MAXN],head[MAXN]; int dist[MAXK][MAXN]; vector< int > a[MAXK]; template <typename T> inline void chkmax(T &x,T y) { x = max(x,y); } template <typename T> inline void chkmin(T &x,T y) { x = min(x,y); } template <typename T> inline void read(T &x) { T f = 1; x = 0; char c = getchar(); for (; !isdigit(c); c = getchar()) if (c == '-') f = -f; for (; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + c - '0'; x *= f; } inline void addedge(int u,int v) { tot++; e[tot] = (edge){v,head[u]}; head[u] = tot; } int main() { read(n); read(m); read(k); read(s); for (int i = 1; i <= n; i++) { int x; read(x); a[x].push_back(i); } for (int i = 1; i <= m; i++) { int u , v; read(u); read(v); addedge(u,v); addedge(v,u); } for (int i = 1; i <= k; i++) { queue< int > q; while (!q.empty()) q.pop(); for (int j = 1; j <= n; j++) dist[i][j] = inf; for (unsigned j = 0; j < a[i].size(); j++) { dist[i][a[i][j]] = 0; q.push(a[i][j]); } while (!q.empty()) { int cur = q.front(); q.pop(); for (int j = head[cur]; j; j = e[j].nxt) { int v = e[j].to; if (dist[i][cur] + 1 < dist[i][v]) { dist[i][v] = dist[i][cur] + 1; q.push(v); } } } } for (int i = 1; i <= n; i++) { for (int j = 1; j <= k; j++) value[j] = dist[j][i]; sort(value + 1,value + k + 1); int ans = 0; for (int j = 1; j <= s; j++) ans += value[j]; printf("%d ",ans); } printf(" "); return 0; }