一个题目数据小就是那个题目的突破点(一般),比如这个题目,大家貌似都能想到n^2的,但是大家看一眼k的大小会发现,这题的突破点在k(这题不是水题= - =).考虑对于没种颜色做一次bfs,算出其他点到这种颜色的最短距离.
代码如下:
#include <bits/stdc++.h>
using namespace std;
const int N=1e5+5,M=105;
int w[N],ans[N];
vector<int>v[N];
int dis[N][M];
vector<int>col[M];
int vis[N];
queue<int>q;
void bfs(int x)
{
while(q.size())
{
int temp=q.front();
q.pop();
for(int i=0;i<v[temp].size();i++)
{
int pos=v[temp][i];
if(vis[pos]) continue;
q.push(pos);
dis[pos][x]+=dis[temp][x]+1;
vis[pos]=1;
}
}
}
int main()
{
int n,m,k,s;
//memset(dis,-1,sizeof dis);
scanf("%d%d%d%d",&n,&m,&k,&s);
for(int i=1;i<=n;i++)
{
scanf("%d",&w[i]);//输入每个点的颜色.
col[w[i]].push_back(i);
}
while(m--)
{
int x,y;
scanf("%d%d",&x,&y);
v[x].push_back(y);
v[y].push_back(x);
}
for(int i=1;i<=k;i++)
{
memset(vis,0,sizeof vis);
for(int j=0;j<col[i].size();j++)
{
q.push(col[i][j]);
vis[col[i][j]]=1;
dis[col[i][j]][i]=0;
}
bfs(i);
}
for(int i=1;i<=n;i++)
{
sort(dis[i]+1,dis[i]+1+k);
for(int j=1;j<=s;j++)
{
// if(i==1) cout<<dis[i][j]<<' ';
ans[i]+=dis[i][j];
}
}//cout<<endl;
for(int i=1;i<=n;i++) printf("%d ",ans[i]);
printf("\n");
return 0;
}

京公网安备 11010502036488号