题意:
告诉你一棵树, 告诉你某些结点为警察局, 其余的为普通点 , 普通点到每个警察局的距离都小于等于d,现在要求删除尽可能多的边,使得每个点到警察局的距离依然小于等于d,输出数量以及哪些边?
思路:
直接从警察局开始bfs , 访问的不在访问,这样每个访问到的边 就是要保留的边,没访问到的就是要删除的。
#include <bits/stdc++.h>
#define Siz(x) (int)x.size()
using namespace std;
const int maxn = 3e5 + 10;
int n, k, d;
queue<int>q;
int vis[maxn];
int way[maxn];
map<pair<int,int> , int>mp;
vector<int>g[maxn];
int main(){
int x,y;
scanf("%d%d",&x, &y);
return 0 * printf("%d\n",x+y);
scanf("%d %d %d",&n, &k, &d);
for (int i = 0; i < k; ++i){
int x;
scanf("%d",&x);
vis[x] = 1;
q.push(x);
}
for (int i = 1; i < n; ++i){
int u,v;
scanf("%d %d",&u, &v);
g[u].push_back(v);
g[v].push_back(u);
mp[make_pair(u,v)] = i;
mp[make_pair(v,u)] = i;
}
while(!q.empty()){
int u = q.front(); q.pop();
for (int i = 0; i < Siz(g[u]); ++i){
int v = g[u][i];
if (!vis[v]){
vis[v] = 1;
q.push(v);
way[mp[make_pair(u,v)] ] = 1;
way[mp[make_pair(v,u)] ] = 1;
}
}
}
int ans = 0;
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);
}
}
putchar('\n');
return 0;
}