CF 986A Fair——多源bfs

题目:http://codeforces.com/contest/986/problem/A

如果从每个村庄开始bfs找货物,会超时。

发现k较小。那就从货物开始bfs,给村庄赋上dis[ 该货物 ]。

但这样还是n^2。考虑有相同货物的村庄,其实可以一起bfs。就是多源bfs。这样就是n*k的了。

多源bfs就是把一些起始点的dis全赋了初值0,然后都放进队列里,之后正常bfs。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=1e5+5,K=105;
int n,m,k,s,head[N],xnt,dis[N][K],a[N],q[K][N],h,t[K];
struct Ed{
  int next,to;
  Ed(int n=0,int t=0):next(n),to(t) {}
}ed[N<<1];
void add(int x,int y)
{
  ed[++xnt]=Ed(head[x],y);head[x]=xnt;
  ed[++xnt]=Ed(head[y],x);head[y]=xnt;
}
int main()
{
  scanf("%d%d%d%d",&n,&m,&k,&s);
  memset(dis,0x3f,sizeof dis);
  for(int i=1;i<=n;i++)
    {
      scanf("%d",&a[i]);dis[i][a[i]]=0;
      q[a[i]][++t[a[i]]]=i;
    }
  int x,y;
  for(int i=1;i<=m;i++)
    {
      scanf("%d%d",&x,&y);add(x,y);
    }
  for(int i=1;i<=k;i++)
    {
      h=1;
      while(h<=t[i])
    {
      int k=q[i][h++];
      for(int j=head[k],v;j;j=ed[j].next)
        if(dis[v=ed[j].to][i]>dis[k][i]+1)
          {
        dis[v][i]=dis[k][i]+1;q[i][++t[i]]=v;
          }
    }
    }
      for(int i=1;i<=n;i++)
    {
      int ans=0;sort(dis[i]+1,dis[i]+k+1);
      for(int j=1;j<=s;j++)ans+=dis[i][j];
      printf("%d ",ans);
    }
      return 0;
}

 

posted on 2018-07-06 21:14  Narh  阅读(138)  评论(0编辑  收藏  举报

导航