题目链接: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 " , ans); for(int i = 1 ; i < n ; i++) { if(!way[i]) { printf("%d " , i); } } printf(" "); return 0; }