题目链接:http://codeforces.com/contest/796/problem/D
题意:n座城市n-1条道路,k个警局,要满足每座城市到一个警局的距离要小于等于d。问最多能删掉多少条路
而且肯定有解。
题解:由于题目说肯定有解,那么直接bfs所有警局如果搜索到同一点那么ans++,同时标记这条路要被删掉。
为什么不用dfs,如果用dfs会出现问题举个例子
p-0-0-0-0-0-p
|
0
|
0
|
p
d为3如果dfs深度设为3,然后会发现这样考虑后又一个点会遍历不到。
最好是用bfs。因为,一定能满足,那么同时从各个警局出发是绝对不会有矛盾的。
#include <iostream>
#include <cstring>
#include <cstdio>
#include <vector>
#include <queue>
using namespace std;
const int M = 3e5 + 10;
int p[M] , n , k , d , ans , way[M];
bool vis[M] , de[M];
struct TnT {
TnT(int v , int id):v(v) , id(id) {}
int v , id;
};
vector<TnT>vc[M];
queue<int>q;
int main() {
scanf("%d%d%d" , &n , &k , &d);
memset(vis , false , sizeof(vis));
q.empty();
for(int i = 1 ; i <= k ; i++) {
scanf("%d" , &p[i]);
vis[p[i]] = true;
q.push(p[i]);
}
for(int i = 1 ; i < n ; i++) {
way[i] = 0;
int x , y;
scanf("%d%d" , &x , &y);
vc[x].push_back(TnT(y , i));
vc[y].push_back(TnT(x , i));
}
ans = 0;
while(!q.empty()) {
int u = q.front();
q.pop();
for (int i = 0; i < vc[u].size(); i++) {
if(!vis[vc[u][i].v]) {
way[vc[u][i].id] = 1;
q.push(vc[u][i].v);
vis[vc[u][i].v] = true;
}
}
}
for(int i = 1 ; i < n ; i++) {
if(!way[i]) {
ans++;
}
}
printf("%d\n" , ans);
for(int i = 1 ; i < n ; i++) {
if(!way[i]) {
printf("%d " , i);
}
}
printf("\n");
return 0;
}