对于每一种颜色 以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;
}