对于每一种颜色 以0为超级源点 向所有该种颜色的点建边 这样每个点都可以得到所有颜色的最近道路 跑k次最短路
然后对于每一个点 在所有k种颜色中 取距离最近的s个即可
后来发现 这是个无权图 还跑什么最短路 直接BFS不就行了 智障啊!
#include <bits/stdc++.h> using namespace std; struct node1 { int v; int next; }; struct node2 { bool friend operator < (node2 n1,node2 n2) { return n1.val>n2.val; } int id; int val; }; node1 edge[400010]; priority_queue <node2> que; int clr[100010],first[100010],dis[110][100010],book[100010],pre[110],ans[100010]; int n,m,k,s,num; void addedge(int u,int v) { edge[num].v=v; edge[num].next=first[u]; first[u]=num++; return; } void dijkstra(int k) { node2 cur,tem; int i,u,v,w; while(!que.empty()) que.pop(); memset(dis[k],0x3f,sizeof(dis[k])); memset(book,0,sizeof(book)); first[0]=-1; for(i=1;i<=n;i++) { if(clr[i]==k) { addedge(0,i); } } tem.id=0,tem.val=0; que.push(tem); dis[k][0]=0; while(!que.empty()) { cur=que.top(); que.pop(); u=cur.id; if(book[u]) continue; book[u]=1; for(i=first[u];i!=-1;i=edge[i].next) { v=edge[i].v; if(u==0) w=0; else w=1; if(!book[v]&&dis[k][v]>dis[k][u]+w) { dis[k][v]=dis[k][u]+w; tem.id=v; tem.val=dis[k][v]; que.push(tem); } } } return; } int main() { int i,j,u,v; scanf("%d%d%d%d",&n,&m,&k,&s); for(i=1;i<=n;i++) { scanf("%d",&clr[i]); } memset(first,-1,sizeof(first)); num=0; for(i=1;i<=m;i++) { scanf("%d%d",&u,&v); addedge(u,v); addedge(v,u); } for(i=1;i<=k;i++) { dijkstra(i); } for(i=1;i<=n;i++) { for(j=1;j<=k;j++) { pre[j]=dis[j][i]; } sort(pre+1,pre+k+1); for(j=1;j<=s;j++) { ans[i]+=pre[j]; } } for(i=1;i<=n;i++) { printf("%d ",ans[i]); } return 0; }