描述
题解
这是去年河南 ACM 省赛的一道题,一眼就能看出来是搜索,这个搜索比较适合用 bfs(),遍历一遍树即可。
首先我们先用 O(n2) 复杂度建图,实际上就是一棵树,建好树后从根节点开始层序遍历,复杂度是 O(n) ,总得来说,这个题的复杂度是 O(T(n2+n)) ,也就是 O(Tn2) ,只要熟练 bfs(),这个代码没啥需要特别注意的。然而去年省赛时我竟然看都没看这道题……
代码
#include <iostream>
#include <algorithm>
#include <cmath>
#include <vector>
#include <cstdio>
#include <queue>
using namespace std;
const int MAXN = 1111;
const double ESP = 1e-6;
const double INITE = 10000; // 驱动轮能量
int N;
double Xt, Yt;
int root = -1, last = -1;
struct gear
{
int pos;
double x, y, r;
double e, sum;
int flag;
} gr[MAXN];
vector<int> vi[MAXN];
int charge(int i, int j)
{
double a = (gr[i].x - gr[j].x) * (gr[i].x - gr[j].x);
double b = (gr[i].y - gr[j].y) * (gr[i].y - gr[j].y);
double c = (gr[i].r + gr[j].r) * (gr[i].r + gr[j].r);
if (fabs(a + b - c) < ESP)
{
return 1;
}
return 0;
}
void bfs()
{
queue<gear> qg;
qg.push(gr[root]);
while (!qg.empty())
{
gear g = qg.front();
qg.pop();
for (int i = 0; i < vi[g.pos].size(); i++)
{
int pos = gr[vi[g.pos][i]].pos;
if (!gr[pos].flag)
{
gr[pos].flag = 1;
gr[pos].e = -gr[g.pos].e * gr[g.pos].r / gr[pos].r;
gr[pos].sum = gr[g.pos].sum + fabs(gr[pos].e);
if (pos == last)
{
printf("%d\n", (int)gr[pos].sum);
return ;
}
qg.push(gr[pos]);
}
}
}
}
int main()
{
int T;
cin >> T;
while (T--)
{
for (int i = 0; i < MAXN; i++)
{
vi[i].clear();
}
cin >> N >> Xt >> Yt;
for (int i = 0; i < N; i++)
{
scanf("%lf%lf%lf", &gr[i].x, &gr[i].y, &gr[i].r);
gr[i].pos = i;
gr[i].flag = 0;
if (gr[i].x == 0 && gr[i].y == 0)
{
root = i;
gr[i].e = INITE;
gr[i].sum = INITE;
gr[i].flag = 1;
}
if (gr[i].x == Xt && gr[i].y == Yt)
{
last = i;
}
}
if (root == last)
{
cout << INITE << '\n';
continue;
}
for (int i = 0; i < N; i++)
{
for (int j = 0; j < N; j++)
{
if (i != j && charge(i, j))
{
vi[i].push_back(j);
vi[j].push_back(i);
}
}
}
bfs();
}
return 0;
}