zoukankan      html  css  js  c++  java
  • CodeForces 337D Book of Evil

    题目链接:http://codeforces.com/contest/337/problem/D

    题目大意:

      给定一棵树,树的某个节点存在一本恶魔之书,能使所有到该点的距离小于d的所有点出现幽灵,现在给出m个出现幽灵的点,问可能存在恶魔之书的节点有多少个。

    分析:

      先找出相距最远的2个幽灵节点(由于每条边的距离为1,所以可以用bfs,不然就只能用Dijkstra),然后各自以幽灵节点自身为中心,向外bfs C层(C <= d),把这些层的节点都放入一个集合,最后两个集合求交就是答案了。
      由于是树型结构,所以只要包含了相距最远的2个幽灵节点就包含了所有幽灵节点,可以用反证法证明。
      幽灵节点本身也有可能放书。

    代码如下:

      1 #include <bits/stdc++.h>
      2 using namespace std;
      3  
      4 #define rep(i,n) for (int i = 0; i < (n); ++i)
      5 #define For(i,s,t) for (int i = (s); i <= (t); ++i)
      6 #define rFor(i,t,s) for (int i = (t); i >= (s); --i)
      7 #define foreach(i,c) for (__typeof(c.begin()) i = c.begin(); i != c.end(); ++i)
      8 #define rforeach(i,c) for (__typeof(c.rbegin()) i = c.rbegin(); i != c.rend(); ++i)
      9  
     10 #define pr(x) cout << #x << " = " << x << "  "
     11 #define prln(x) cout << #x << " = " << x << endl
     12  
     13 #define LOWBIT(x) ((x)&(-x))
     14  
     15 #define ALL(x) x.begin(),x.end()
     16 #define INS(x) inserter(x,x.begin())
     17  
     18 #define ms0(a) memset(a,0,sizeof(a))
     19 #define msI(a) memset(a,inf,sizeof(a))
     20 #define msM(a) memset(a,-1,sizeof(a))
     21  
     22 #define pii pair<int,int> 
     23 #define piii pair<pair<int,int>,int> 
     24 #define mp make_pair
     25 #define pb push_back
     26 #define fi first
     27 #define se second
     28  
     29 inline int gc(){
     30     static const int BUF = 1e7;
     31     static char buf[BUF], *bg = buf + BUF, *ed = bg;
     32      
     33     if(bg == ed) fread(bg = buf, 1, BUF, stdin);
     34     return *bg++;
     35 } 
     36  
     37 inline int ri(){
     38     int x = 0, f = 1, c = gc();
     39     for(; c<48||c>57; f = c=='-'?-1:f, c=gc());
     40     for(; c>47&&c<58; x = x*10 + c - 48, c=gc());
     41     return x*f;
     42 }
     43  
     44 typedef long long LL;
     45 typedef unsigned long long uLL;
     46 const int inf = 1e9 + 9;
     47 const LL mod = 1e9 + 7;
     48 const int maxN = 1e5 + 7;
     49  
     50 struct Node{
     51     vector< int > next;
     52 };
     53  
     54 int n, m, d, ans;
     55 int vis[maxN];
     56 int ghost[maxN]; // 记录是否是幽灵 
     57 int state[maxN]; // 标记是否可能存在书,值为2的时候才存在 
     58 Node nodes[maxN];
     59 queue< int > Q;
     60  
     61 int g_1, g_2; // 最远幽灵点对 
     62  
     63 // 返回与幽灵节点x距离最远的幽灵节点的幽灵节点序号 
     64 int bfs_1(int x) {
     65     int dist = 1;
     66     int cnt = m - 1, cnt_1 = 1;
     67     if(cnt == 0) return x;
     68     while(!Q.empty()) Q.pop();
     69     ms0(vis);
     70     vis[x] = 1; 
     71     Q.push(x);
     72      
     73     while(!Q.empty()) {
     74         --cnt_1;
     75         if(dist > 2 * d) return -1;
     76         int tmp = Q.front();
     77         Q.pop();
     78          
     79         foreach(i, nodes[tmp].next) {
     80             if(vis[*i]) continue;
     81             vis[*i] = 1;
     82             if(ghost[*i] == 1) {
     83                 --cnt;
     84                 if(cnt == 0) return *i;
     85             }
     86             Q.push(*i);
     87         }
     88         if(cnt_1 == 0) {
     89             ++dist;
     90             cnt_1 = Q.size();
     91         }
     92     }
     93 }
     94  
     95 // 以幽灵节点x为中心,向外bfs,记录所有与x距离小于等于d的节点,自身节点也算 
     96 void bfs_2(int x) {
     97     int dist = 1, cnt_1 = 1;
     98     while(!Q.empty()) Q.pop();
     99     ms0(vis);
    100     vis[x] = 1; 
    101     Q.push(x);
    102     ++state[x];
    103      
    104     while(!Q.empty()) {
    105         --cnt_1;
    106         if(dist > d) return;
    107         int tmp = Q.front();
    108         Q.pop();
    109          
    110         foreach(i, nodes[tmp].next) {
    111             if(vis[*i]) continue;
    112             vis[*i] = 1;
    113             ++state[*i];
    114             Q.push(*i);
    115         }
    116         if(cnt_1 == 0) {
    117             ++dist;
    118             cnt_1 = Q.size();
    119         }
    120     }
    121 }
    122  
    123 int main(){
    124     cin >> n >> m >> d;
    125     For(i, 1, m) {
    126         cin >> g_1;
    127         ghost[g_1] = 1;
    128     }
    129      
    130     For(i, 1, n-1) {
    131         int x, y;
    132         cin >> x >> y;
    133         nodes[x].next.push_back(y);
    134         nodes[y].next.push_back(x);
    135     }
    136      
    137     g_2 = bfs_1(g_1); 
    138     g_1 = bfs_1(g_2); 
    139      
    140     if(g_1 != -1 && g_2 != -1) {
    141         bfs_2(g_1);
    142         bfs_2(g_2);
    143          
    144         For(i, 1, n) if(state[i] == 2) ++ans;
    145     }
    146      
    147     cout << ans << endl;
    148     return 0;
    149 }
    150  
    151 /*
    152 25 7 8
    153 2 6 9 13 20 17 23
    154 1 2
    155 1 3
    156 1 4
    157 2 5
    158 5 8
    159 5 9
    160 8 15
    161 9 16
    162 3 6
    163 6 10
    164 6 11
    165 6 12
    166 6 13
    167 11 17
    168 17 22
    169 17 23
    170 12 18
    171 4 7
    172 7 14
    173 14 19
    174 14 20
    175 20 24
    176 20 25
    177 14 21
    178  
    179 ans: 16
    180 */
    View Code
  • 相关阅读:
    git log后怎么退出?
    nuxt项目中怎么使用iconfont图标
    navicat连接远程数据库mysql报错2013解决方法
    navicat15激活使用
    picgo软件使用
    设置yarn源修改为淘宝源
    nuxt项目修改本地运行的端口
    nuxt项目中使用less全局样式、全局变量的配置
    带环链表 linked list cycle
    Delete a Node in Single Linked List删除单链列表中的节点
  • 原文地址:https://www.cnblogs.com/zaq19970105/p/10752586.html
Copyright © 2011-2022 走看看