搜索每种东西能去各个城市的最短路。
然后每个城市排序求出最小值就好了。
妙啊。
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
using namespace std;
const int inf = 0x3f3f3f3f;
const int N = 1e5 + 10;
int a[N];
struct node
{
int v, nxt;
}e[N * 2];
int vis[N][110], head[N], cnt;
int dist[N][110];
void add(int u, int v)
{
e[++cnt].v = v;
e[cnt].nxt = head[u];
head[u] = cnt;
}
queue<int>q[N];
void dfs(int x)
{
while (!q[x].empty())
{
int u = q[x].front(); q[x].pop();
for (int i = head[u]; i; i = e[i].nxt)
{
int v = e[i].v;
if (vis[v][x])continue;
dist[v][x] = dist[u][x] + 1;
vis[v][x] = 1;
q[x].push(v);
}
}
}
int main()
{
int n, m, k, s;
scanf("%d%d%d%d", &n, &m, &k, &s);
int u, v;
for (int i = 1; i <= n; i++)
{
scanf("%d", &a[i]);
q[a[i]].push(i);
vis[i][a[i]] = 1;
}
for (int i = 1; i <= m; i++)
{
scanf("%d%d", &u, &v);
add(u, v);
add(v, u);
}
for (int i = 1; i <= k; i++)
{
dfs(i);
}
int ans;
for (int i = 1; i <= n; i++)
{
ans = 0;
sort(dist[i] + 1, dist[i] + k + 1);
for (int j = 1; j <= s; j++)ans += dist[i][j];
printf("%d ", ans);
}
cout << endl;
return 0;
}