题意: 给你n个城市,m条路径,和s种货物,和一个k,之后让你从每个点开始,走,收集到k种货物的最短路
思路:由于n是1e5,你直接每个点去广搜肯定是不对滴会超时,但是s只有100,所以我们可以从s只有100这个方向去考虑,仔细想想我们其实可以想到,我们设dis[i][j]表示的是第j个物品到第i个城市的最短路,这样的话,对于每个一个城市i,我们去排一个序,然后每次只取前k个就好了。
代码:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5+10;
int a[maxn],dis[maxn][150]; // 表示的是第j个物品到第i个城市的最短路
int vis[maxn];
int n,m,k,s;
vector<int>G[maxn];
void bfs(int g)
{
memset(vis,0,sizeof(vis));
queue<int>que;
for(int i = 1 ; i <= n ; i++)
{
if(a[i] == g)
{
que.push(i);
// printf(" I = %d \n",i); // 多源最短路把所有起点都压进去
dis[i][g] = 0;
vis[i] = 1;
}
}
while(!que.empty())
{
int u = que.front();
que.pop();
for(int i = 0 ; i < G[u].size() ; i ++)
{
int v = G[u][i];
if(!vis[v])
{
vis[v] = 1;
dis[v][g] = dis[u][g] + 1;
que.push(v);
}
}
}
}
int main()
{
while(scanf("%d%d%d%d",&n,&m,&k,&s)!=EOF)
{
memset(dis,127,sizeof(dis));
int x,y;
for(int i = 1 ; i <= n ; i++) scanf("%d",&a[i]);
for(int i = 0 ; i < m ; i++)
{
scanf("%d%d",&x,&y);
G[x].push_back(y);
G[y].push_back(x);
}
for(int i = 1 ; i <= k ; i++)
{
bfs(i);
}
for(int i = 1 ; i <= n ; i++)
{
int ans = 0;
sort(dis[i]+1,dis[i]+1+k);
// for(int j = 1 ; j <= s ; j++) printf("%d ",dis[i][j]);puts("");
for(int j = 1 ; j <= s ; j++)
{
ans += dis[i][j];
}
printf("%d ",ans);
}
puts("");
}
}