[UVa 1267]Network

题解

我们将图中给出的$VOD$为根建立有根树,每次取出未覆盖的最深的节点第$k$级祖先,将其建为$VOD$,遍历一遍,将能够盖到的点标记。重复,直到盖完。贪心正确性可以证明。

  1 //It is made by Awson on 2017.9.16
  2 #include <map>
  3 #include <set>
  4 #include <cmath>
  5 #include <ctime>
  6 #include <queue>
  7 #include <stack>
  8 #include <cstdio>
  9 #include <string>
 10 #include <vector>
 11 #include <cstdlib>
 12 #include <cstring>
 13 #include <iostream>
 14 #include <algorithm>
 15 #define LL long long
 16 #define Max(a, b) ((a) > (b) ? (a) : (b))
 17 #define Min(a, b) ((a) < (b) ? (a) : (b))
 18 #define Abs(a) ((a) < 0 ? (-(a)) : (a))
 19 using namespace std;
 20 const int N = 1000;
 21 
 22 int n, s, k, u, v;
 23 struct tt {
 24     int to, next;
 25 }edge[N*2+5];
 26 int path[N+5], top;
 27 
 28 int dep[N+5], fa[N+5];
 29 bool isleave[N+5];
 30 
 31 struct node {
 32     int u, dist;
 33     node () {
 34     }
 35     node (int _u,int _dist) {
 36         u = _u; dist = _dist;
 37     }
 38     bool operator < (const node & b) const{
 39         return dist < b.dist;
 40     }
 41 };
 42 priority_queue<node>Q;
 43 
 44 int get_father(int u, int kth) {
 45     if (!kth) return u;
 46     return get_father(fa[u], kth-1);
 47 }
 48 void dfs2(int u, int kth) {
 49     isleave[u] = false;
 50     if (!kth) return;
 51     for (int i = path[u]; i; i = edge[i].next)
 52         dfs2(edge[i].to, kth-1);
 53 }
 54 void dfs(int u, int depth) {
 55     dep[u] = depth;
 56     for (int i = path[u]; i; i = edge[i].next)
 57         if (dep[edge[i].to] == -1) {
 58             dfs(edge[i].to, depth+1);
 59             fa[edge[i].to] = u;
 60             isleave[u] = false;
 61         }
 62 }
 63 void add(int u, int v) {
 64     edge[++top].to = v;
 65     edge[top].next = path[u];
 66     path[u] = top;
 67 }
 68 void work() {
 69     memset(path, 0, sizeof(path)); top = 0;
 70     memset(dep, -1, sizeof(dep));
 71     memset(isleave, 1, sizeof(isleave));
 72     memset(fa, 0, sizeof(fa));
 73     scanf("%d%d%d", &n, &s, &k);
 74     for (int i = 1; i < n; i++) {
 75         scanf("%d%d", &u, &v);
 76         add(u, v); add(v, u);
 77     }
 78     dfs(s, 0);
 79     for (int i = 1; i <= n; i++)
 80         if (isleave[i] && dep[i] > k) {
 81             Q.push(node(i,dep[i]));
 82         }
 83     int ans = 0;
 84     while (!Q.empty()) {        
 85         while (!isleave[Q.top().u]) {
 86             Q.pop();
 87             if (Q.empty()) break;
 88         }
 89         if (Q.empty()) break;
 90         int father = get_father(Q.top().u, k);
 91         dfs2(father, k);
 92         ans++;
 93     }
 94     printf("%d\n", ans);
 95 }
 96 int main() {
 97     int t;
 98     scanf("%d", &t);
 99     while (t--)
100         work();
101     return 0;
102 }

 

posted @ 2017-09-17 12:24  NaVi_Awson  阅读(253)  评论(0编辑  收藏  举报