首页 > 代码库 > 796D(bfs)

796D(bfs)

题目链接: http://codeforces.com/problemset/problem/796/D

 

题意: 给出一颗 n 个节点树, 树枝连接的两个定点距离为 1, 树中有 k 个特殊点, 问最多可以删除哪些树枝, 使得树中其他顶点到特殊点的最小距离不大于 d.

注意: 题目说明了一定有解.

 

思路: bfs

可以直接 bfs 求其他点到特殊点的最短距离, 因为题目说明给出的数据都是有解的, 即所有顶点到特殊点的距离都是不大于 d 的. 那么搜完所有顶点后剩余的边就是不必要的.  即答案中的可删除边.

 

代码:

技术分享
 1 #include <iostream>
 2 #include <stdio.h>
 3 #include <vector>
 4 #include <queue>
 5 #include <map>
 6 using namespace std;
 7 
 8 const int MAXN = 3e5 + 10;
 9 int vis[MAXN], tag[MAXN];
10 map<pair<int, int>, int> mp;
11 vector<int> vt[MAXN];
12 queue<int> q;
13 
14 int main(void){
15     int n, k, d, x, y, ans = 0;
16     scanf("%d%d%d", &n, &k, &d);
17     for(int i = 0; i < k; i++){
18         scanf("%d", &x);
19         q.push(x);
20         vis[x] = 1;
21     }
22     for(int i = 1; i <= n - 1; i++){
23         scanf("%d%d", &x, &y);
24         vt[x].push_back(y);
25         vt[y].push_back(x);
26         mp[{x, y}] = mp[{y, x}] = i;
27     }
28     while(!q.empty()){
29         int p = q.front();
30         q.pop();
31         for(int i = 0; i < vt[p].size(); i++){
32             if(!vis[vt[p][i]]){
33                 vis[vt[p][i]] = 1;
34                 q.push(vt[p][i]);
35                 tag[mp[{p, vt[p][i]}]] = 1;
36                 ans++;
37             }
38         }
39     }
40     cout << n - ans - 1 << endl;
41     for(int i = 1; i <= n - 1; i++){
42         if(!tag[i]) cout << i << " ";
43     }
44     cout << endl;
45     return 0;
46 }
View Code

 

796D(bfs)