BFS一定要在搜索前检查是否满足结束条件,不然可能会超时!
附上原题:189010.种树安排
来源:CODEFORCES
难度普及/提高-
内存128MB 时间4000ms 题目描述
植树节到了, 名学生一共种植了 棵树,这些树可以看作数轴上的点。现在请你给每个人安排一个位置进行合影留念,要求所有人到离他最近的树的距离之和最小。注意,所有树和人的位置都不可以重叠。
输入格式 第一行两个整数n 和 m ,表示树的数量和学生数; 第二行 n个数ai ,表示每棵树的位置。
输出格式 第一行一个数,表示最小的距离和。 第二行 m 个数,表示每个人的位置。 任意输出一种可行的安排即可。
输入输出测试点
输入
2 6
1 5
输出
8 -1 2 6 4 0 3 输入 3 5
0 3 1
输出
7
5 -2 4 -1 2 ```c #include<bits/stdc++.h> using namespace std; int tr[2000005]; int p[2000005]; unordered_map<int,bool> mp; int n,m; long long ans; int dx[2]{-1,1}; struct people{ int zb,rc; }; void bfs() { queue q; for(int i=1;i<=n;i++) { q.push({tr[i],tr[i]}); mp[tr[i]]=1; } int y=0; while(!q.empty()) { people now=q.front(); q.pop(); if(y==m) { return; } for(int i=0;i<2;i++) { int x=now.zb+dx[i]; if(mp[x]==0) { y++; q.push({x,now.rc}); mp[x]=1; p[y]=x; ans+=abs(p[y]-now.rc); } } } return; } int main() { cin>>n>>m; for(int i=1;i<=n;i++) { scanf("%d",&tr[i]); } bfs(); cout<<ans; cout<<endl; for(int i=1;i<=m;i++) { cout<<p[i]<<" "; } }
注意代码if(y==m)一行;要是测试点为1 1 0就会死循环
而下面这么写就不会有问题
```c
#include<bits/stdc++.h>
using namespace std;
int tr[2000005];
int p[2000005];
unordered_map<int,bool> mp;
int n,m;
long long ans;
int dx[2]{-1,1};
struct people{
int zb,rc;
};
void bfs()
{
queue<people> q;
for(int i=1;i<=n;i++)
{
q.push({tr[i],tr[i]});
mp[tr[i]]=1;
}
int y=0;
while(!q.empty())
{
people now=q.front();
q.pop();
for(int i=0;i<2;i++)
{
if(y==m)
{
return;
}
int x=now.zb+dx[i];
if(mp[x]==0)
{
y++;
q.push({x,now.rc});
mp[x]=1;
p[y]=x;
ans+=abs(p[y]-now.rc);
}
}
}
return;
}
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
{
scanf("%d",&tr[i]);
}
bfs();
cout<<ans;
cout<<endl;
for(int i=1;i<=m;i++)
{
cout<<p[i]<<" ";
}
}