1. 程式人生 > >CodeForces - 986A Fair (BFS+貪心)

CodeForces - 986A Fair (BFS+貪心)

int ron push_back mes force val back 全部 ORC

題意:有N個點M條邊的無向圖,每個點有給定的ai(1<=ai<=K,K<=200)表示該點擁有的物品編號,保證1-K在N個點全部出現。求每個點收集S個不同的物品所要走過的最短路程(邊的長度為1)。

分析:N是1e5,如果直接對每個點搜索肯定超時。發現K的範圍很小,而且1-K全部覆蓋。那麽考慮對所有1-K的值BFS,用一個二維數組dp[i][j]記錄i點要獲取編號為j的物品最少走過的路程,並對每個點取最小的S個物品對應的路徑。

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const
int maxn =1e5+5; int a[maxn]; int res[maxn]; vector<int> G[maxn]; bool vis[maxn]; int d[maxn][305]; void init(int N) {for(int i=1;i<=N;++i) G[i].clear();} void AddEdge(int u,int v){G[u].push_back(v);} void BFS(int val,int N) { memset(vis,0,sizeof(vis)); queue<int> Q; for
(int i=1;i<=N;++i){ if(a[i]==val){ vis[i]=true; Q.push(i); } } while(!Q.empty()){ int x =Q.front();Q.pop(); for(int i=0;i<G[x].size();++i){ int v = G[x][i]; if(!vis[v]){ vis[v] = true; d[v][val]
= d[x][val]+1; Q.push(v); } } } } int main() { #ifndef ONLINE_JUDGE freopen("in.txt","r",stdin); freopen("out.txt","w",stdout); #endif int N,M,K,S,u,v; while(scanf("%d%d%d%d",&N,&M,&K,&S)==4){ init(N); memset(d,0,sizeof(d)); for(int i=1;i<=N;++i) scanf("%d",&a[i]); for(int i=1;i<=M;++i){ scanf("%d%d",&u,&v); AddEdge(u,v); AddEdge(v,u); } for(int i=1;i<=K;++i){ memset(vis,0,sizeof(vis)); BFS(i,N); } for(int i=1;i<=N;++i){ sort(d[i]+1,d[i]+K+1); res[i]=0; for(int j =1;j<=S;++j){ res[i]+=d[i][j]; } } for(int i=1;i<N;++i) printf("%d ",res[i]); printf("%d\n",res[N]); } return 0; }

CodeForces - 986A Fair (BFS+貪心)