codeforces987D bfs跑最短路
http://codeforces.com/contest/987/problem/D
题意:有N个城市,M条双向道路连接两个城市(边权为 1 ),整个图保证连通。有K种物品,但每个城市只有一种,现在它们都需要S种物品来举办展览,可以去其他城市获取该城市的物品,花费是两城市之间的最短路径长度。求每个城市举办展览的最小花费。
分析:如果我们正面求解肯定TLE因为1e5数据很大,不妨我们逆向考虑一下,考虑物品 i 到小镇 j 的距离(dist [ j ][ x ]表示 )即以物品i为源点跑bfs;最后对k个物品进行bfs走最短路,然后不断更新与其他小镇的距离,对后进行sort排序一下取前s个即可。
代码::
#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll MOD=998244353;
const int maxn=1e5+5;
const int maxnn=105;
int dist[maxn][maxnn];//记录物品i到小镇的距离
vector<int> V[maxn];
#include <stdio.h>
#include <algorithm>
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll MOD=998244353;
const int maxn=1e5+5;
const int maxnn=105;
int dist[maxn][maxnn];//记录物品i到小镇的距离
vector<int> V[maxn];
int ma[maxn];
int res[maxn];
bool vis[maxn];//标记
void bfs(int x,int y)
{
queue<int>que;
memset(vis,0,sizeof(vis));
for(int i=1;i<=y;i++)
{
if(ma[i]==x){//以物品 i 为源点进行最短路;同时标记防止下次搜索找到同样的物品
int res[maxn];
bool vis[maxn];//标记
void bfs(int x,int y)
{
queue<int>que;
memset(vis,0,sizeof(vis));
for(int i=1;i<=y;i++)
{
if(ma[i]==x){//以物品 i 为源点进行最短路;同时标记防止下次搜索找到同样的物品
vis[i]=1;
que.push(i);
}
}
while(!que.empty())
{
int val=que.front();
que.pop();
for(int i=0;i<V[val].size();i++)
{
while(!que.empty())
{
int val=que.front();
que.pop();
for(int i=0;i<V[val].size();i++)
{
int key=V[val][i];
if(!vis[key]){
vis[key]=1;
dist[key][x]=dist[val][x]+1;
que.push(key);
}
}
}
}
int main()
{
int n,m,s,k;
scanf("%d%d%d%d",&n,&m,&k,&s);
for(int i=1;i<=n;i++)
{
scanf("%d",&ma[i]);
}
for(int i=1;i<=m;i++)
{
int a,b;
scanf("%d%d",&a,&b);
V[a].push_back(b);
V[b].push_back(a);
}
for(int i=1;i<=k;i++)
{
if(!vis[key]){
vis[key]=1;
dist[key][x]=dist[val][x]+1;
que.push(key);
}
}
}
}
int main()
{
int n,m,s,k;
scanf("%d%d%d%d",&n,&m,&k,&s);
for(int i=1;i<=n;i++)
{
scanf("%d",&ma[i]);
}
for(int i=1;i<=m;i++)
{
int a,b;
scanf("%d%d",&a,&b);
V[a].push_back(b);
V[b].push_back(a);
}
for(int i=1;i<=k;i++)
{
bfs(i,n);
}
for(int i=1;i<=n;i++)
{
sort(dist[i]+1,dist[i]+k+1);
res[i]=0;
for(int j=1;j<=s;j++)
{
res[i]+=dist[i][j];
}
}
for(int i=1;i<=n;i++)
{
printf("%d ",res[i]);
}
return 0;
}
}
for(int i=1;i<=n;i++)
{
sort(dist[i]+1,dist[i]+k+1);
res[i]=0;
for(int j=1;j<=s;j++)
{
res[i]+=dist[i][j];
}
}
for(int i=1;i<=n;i++)
{
printf("%d ",res[i]);
}
return 0;
}
纵使单枪匹马,也要勇闯天涯