思路
题面中给出的数据结构很显然是一棵树,我们需要求能覆盖整棵树的最少的消防局数量。我们先按照要求输入,决定根节点(我这里是1号)之后按深度排序,从深度最深的节点开始检测。如果一个节点没有被覆盖,那么就覆盖他的爷爷节点,这样可以使覆盖面积最大,在覆盖时向两个方向扩散设置vis[i]标记。被标记过的点则跳过,没有被标记的点则把消防局设在爷爷处。由于我们的设置过程是按照深度由深到浅渐进,所以不会存在潜在的问题。
代码
// P2279.cpp
#include <iostream>
#include <stack>
#include <queue>
using namespace std;
const int maxn = 4040;
struct edge
{
int to, next;
} edges[maxn];
int head[maxn];
int F[maxn];
stack<int> st;
bool vis[maxn];
int current = 0;
int n;
void addpath(int src, int dst)
{
edges[current].to = dst;
edges[current].next = head[src];
head[src] = current++;
}
void BFS()
{
queue<int> q;
q.push(1);
st.push(1);
while (!q.empty())
{
int curt = q.front();
q.pop();
for (int i = head[curt]; i != -1; i = edges[i].next)
if (edges[i].to != F[curt])
st.push(edges[i].to), q.push(edges[i].to);
}
}
void DFS(int p, int dep)
{
if (dep > 2)
return;
vis[p] = true;
for (int i = head[p]; i != -1; i = edges[i].next)
DFS(edges[i].to, dep + 1);
}
int main()
{
cin >> n;
fill(head, head + maxn, -1);
fill(vis, vis + maxn, false);
int num = -1;
for (int i = 2; i <= n; i++)
{
cin >> num;
F[i] = num;
addpath(num, i), addpath(i, num);
}
// going to solve;
BFS();
int ans = 0;
while (!st.empty())
{
int curt = st.top();
st.pop();
if (!vis[curt] && ++ans)
DFS(F[F[curt]], 0);
}
cout << ans;
return 0;
}
// P2279.cpp
#include <iostream>
#include <stack>
#include <queue>
using namespace std;
const int maxn = 4040;
struct edge
{
int to, next;
} edges[maxn];
int head[maxn];
int F[maxn];
stack<int> st;
bool vis[maxn];
int current = 0;
int n;
void addpath(int src, int dst)
{
edges[current].to = dst;
edges[current].next = head[src];
head[src] = current++;
}
void BFS()
{
queue<int> q;
q.push(1);
st.push(1);
while (!q.empty())
{
int curt = q.front();
q.pop();
for (int i = head[curt]; i != -1; i = edges[i].next)
if (edges[i].to != F[curt])
st.push(edges[i].to), q.push(edges[i].to);
}
}
void DFS(int p, int dep)
{
if (dep > 2)
return;
vis[p] = true;
for (int i = head[p]; i != -1; i = edges[i].next)
DFS(edges[i].to, dep + 1);
}
int main()
{
cin >> n;
fill(head, head + maxn, -1);
fill(vis, vis + maxn, false);
int num = -1;
for (int i = 2; i <= n; i++)
{
cin >> num;
F[i] = num;
addpath(num, i), addpath(i, num);
}
// going to solve;
BFS();
int ans = 0;
while (!st.empty())
{
int curt = st.top();
st.pop();
if (!vis[curt] && ++ans)
DFS(F[F[curt]], 0);
}
cout << ans;
return 0;
}
// P2279.cpp #include <iostream> #include <stack> #include <queue> using namespace std; const int maxn = 4040; struct edge { int to, next; } edges[maxn]; int head[maxn]; int F[maxn]; stack<int> st; bool vis[maxn]; int current = 0; int n; void addpath(int src, int dst) { edges[current].to = dst; edges[current].next = head[src]; head[src] = current++; } void BFS() { queue<int> q; q.push(1); st.push(1); while (!q.empty()) { int curt = q.front(); q.pop(); for (int i = head[curt]; i != -1; i = edges[i].next) if (edges[i].to != F[curt]) st.push(edges[i].to), q.push(edges[i].to); } } void DFS(int p, int dep) { if (dep > 2) return; vis[p] = true; for (int i = head[p]; i != -1; i = edges[i].next) DFS(edges[i].to, dep + 1); } int main() { cin >> n; fill(head, head + maxn, -1); fill(vis, vis + maxn, false); int num = -1; for (int i = 2; i <= n; i++) { cin >> num; F[i] = num; addpath(num, i), addpath(i, num); } // going to solve; BFS(); int ans = 0; while (!st.empty()) { int curt = st.top(); st.pop(); if (!vis[curt] && ++ans) DFS(F[F[curt]], 0); } cout << ans; return 0; }