CF 987D Fair (思维+BFS)

题意: 给你n个城市,m条路径,和s种货物,和一个k,之后让你从每个点开始,走,收集到k种货物的最短路

思路:由于n是1e5,你直接每个点去广搜肯定是不对滴会超时,但是s只有100,所以我们可以从s只有100这个方向去考虑,仔细想想我们其实可以想到,我们设dis[i][j]表示的是第j个物品到第i个城市的最短路,这样的话,对于每个一个城市i,我们去排一个序,然后每次只取前k个就好了。

代码:

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5+10;
int a[maxn],dis[maxn][150]; // 表示的是第j个物品到第i个城市的最短路 
int vis[maxn];
int n,m,k,s;
vector<int>G[maxn];
void bfs(int g)
{
	memset(vis,0,sizeof(vis));
	queue<int>que;
	for(int i = 1 ; i <= n ; i++)
	{
		if(a[i] == g)
		{
			que.push(i);
		//	printf(" I = %d \n",i);  // 多源最短路把所有起点都压进去
			dis[i][g] = 0;
			vis[i] = 1;
		 } 
	}
	while(!que.empty())
	{
		int u = que.front();
		que.pop();
		for(int i = 0 ; i < G[u].size() ; i ++)
		{
			int v = G[u][i];
			if(!vis[v])
			{
				vis[v] = 1;
				dis[v][g] = dis[u][g] + 1;
				que.push(v);
			}
			
		}
	}
}
int main()
{
	
	while(scanf("%d%d%d%d",&n,&m,&k,&s)!=EOF)
	{
		memset(dis,127,sizeof(dis));
		int x,y;
		for(int i = 1 ; i <= n ; i++) scanf("%d",&a[i]);
		for(int i = 0 ; i < m ; i++)
		{
			scanf("%d%d",&x,&y);
			G[x].push_back(y);
			G[y].push_back(x);
		}
		for(int i = 1 ; i <= k ; i++)
		{
			bfs(i);
		}
		for(int i = 1 ; i <= n ; i++)
		{
			int ans = 0;
			sort(dis[i]+1,dis[i]+1+k);
		//	for(int j = 1 ; j <= s ; j++) printf("%d  ",dis[i][j]);puts(""); 
			for(int j = 1 ; j <= s ; j++)
			{
				ans += dis[i][j]; 
			}
			printf("%d ",ans);
		}
		puts("");
	}
}

猜你喜欢

转载自blog.csdn.net/wjmwsgj/article/details/80520773