Codeforces Round #408 (Div. 2) D. Police Stations

题目链接: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;
}

原文地址:https://www.cnblogs.com/TnT2333333/p/6691961.html