1. 程式人生 > >CF 986A Fair——多源bfs

CF 986A Fair——多源bfs

spa include += space tdi namespace pro name force

題目: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; }

CF 986A Fair——多源bfs