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 }
我就是我,颜色不一样的烟火 --- geloutingyu