题目大意:一个连通图(树型),每个点都是一个城市,有些城市是有警察局的,任何城市都可以到达d距离的警察局,即每个警察局都有一个有效范围d.问你最多可以删除多少条路,使得每个城市依然可以到达警察局。
解题思路:我们可以这样想,既然给了你k个警察局,那当然是每个都要用上才是最优的,每个城市都应该优先选择和它最近的警察局,如果它选择远的,只会多走一些没有必要的路径。所以可以从每个警察局同时开始宽搜,同时标记走过的边,如果图上所有的城市都被标记,那就宽搜结束。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll maxn=3e5+5;
int n,k,d,cnt=0;
bool vis[maxn];
bool edgevis[maxn];
vector<int> added;
struct edge {
int to;
int id;
};
vector<edge> ee[maxn];
struct node {
int p;
int step;
};
queue<node> q;
void bfs(){
while(!q.empty()){
node st=q.front();
int np=st.p,nstep=st.step;
q.pop();
if(nstep>d) continue;
for(int i=0;i<(int)ee[np].size();++i){
edge tt=ee[np][i];
int nto=tt.to,nid=tt.id;
if(!vis[nto]){
vis[nto]=true;
edgevis[nid]=true;
++cnt;
q.push(node{nto,nstep+1});
}
}
}
}
int main() {
scanf("%d%d%d",&n,&k,&d);
memset(vis,false,sizeof(vis));
memset(edgevis,false,sizeof(edgevis));
int tmp;
for(int i=1; i<=k; ++i) {
scanf("%d",&tmp);
q.push(node{tmp,0});
vis[tmp]=true;
}
int x,y;
for(int i=1; i<=n-1; ++i) {
scanf("%d%d",&x,&y);
ee[x].push_back(edge {y,i});
ee[y].push_back(edge {x,i});
}
bfs();
cout<<n-1-cnt<<endl;
for(int i=1; i<=n-1; ++i) {
if(edgevis[i]==false) {
cout<<i<<' ';
}
}
cout<<endl;
return 0;
}