A:对每种商品多源bfs一下每个点到该商品的最近距离,对每个点sort一下取前s个即可。
#include<iostream> #include<cstdio> #include<cmath> #include<cstdlib> #include<cstring> #include<algorithm> using namespace std; #define ll long long #define int long long #define N 100010 int n,m,k,s,a[N],p[N],d[110][N],b[110],q[N],t; int read() { int x=0,f=1;char c=getchar(); while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();} while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar(); return x*f; } struct data{int to,nxt; }edge[N<<1]; void addedge(int x,int y){t++;edge[t].to=y,edge[t].nxt=p[x],p[x]=t;} void bfs(int k) { int head=0,tail=0;memset(d[k],42,sizeof(d[k])); for (int i=1;i<=n;i++) if (a[i]==k) q[++tail]=i,d[k][i]=0; do { int x=q[++head]; for (int i=p[x];i;i=edge[i].nxt) if (d[k][edge[i].to]>d[k][x]) { d[k][edge[i].to]=d[k][x]+1; q[++tail]=edge[i].to; } }while (head<tail); } signed main() { #ifndef ONLINE_JUDGE freopen("a.in","r",stdin); freopen("a.out","w",stdout); #endif n=read(),m=read(),k=read(),s=read(); for (int i=1;i<=n;i++) a[i]=read(); for (int i=1;i<=m;i++) { int x=read(),y=read(); addedge(x,y),addedge(y,x); } for (int i=1;i<=k;i++) bfs(i); for (int i=1;i<=n;i++) { for (int j=1;j<=k;j++) b[j]=d[j][i]; sort(b+1,b+k+1); int ans=0; for (int j=1;j<=s;j++) ans+=b[j]; printf("%d ",ans); } return 0; }