【洛谷】P2712 摄像头

题目地址:

https://www.luogu.com.cn/problem/P2712

题目描述:
食品店里有 n n n 个摄像头,这种摄像头很笨拙,只能拍摄到固定位置。现有一群胆大妄为的松鼠想要抢劫食品店,为了不让摄像头拍下他们犯罪的证据,他们抢劫前的第一件事就是砸毁这些摄像头。
为了便于砸毁摄像头,松鼠歹徒们把所有摄像头和摄像头能监视到的地方统一编号,一个摄像头能被砸毁的条件是该摄像头所在位置不被其他摄像头监视。
现在你的任务是帮松鼠们计算是否可以砸掉所有摄像头,如不能则输出还没砸掉的摄像头的数量。

输入格式:
1 1 1 行,一个整数 n n n,表示摄像头的个数。
2 2 2 n + 1 n+1 n+1 行是摄像头的信息,包括:摄像头的位置 x x x,以及这个摄像头可以监视到的位置数 m m m,之后 m m m 个数 y y y 是此摄像头可以监视到的位置。(砸了这些摄像头之后自然这些位置就监视不到了)

输出格式:
若可以砸掉所有摄像头则输出“ YES \texttt{YES} YES ”,否则输出还没砸掉的摄像头的数量。(不带引号)

数据范围:
1 ≤ n ≤ 100 1 \leq n \leq 100 1n100
0 ≤ m ≤ 100 0 \leq m \leq 100 0m100
0 ≤ x , y ≤ 500 0 \leq x,y \leq 500 0x,y500

先建图,然后做拓扑排序,可以用BFS,注意到入队的时候要判断一下那个位置是否有摄像头,如果没有摄像头的话不需要入队。代码如下:

#include <iostream>
#include <unordered_map>
#include <vector>
using namespace std;

const int N = 110;
int n;
unordered_map<int, vector<int>> g;
unordered_map<int, int> ind;
int q[N];

int topsort() {
  int res = 0;
  int hh = 1, tt = 1;
  for (auto &[k, v] : g)
    if (!ind[k]) q[tt++] = k;
  while (hh < tt) {
    int t = q[hh++];
    res++;
    for (auto &ne : g[t])
      if (g.count(ne) && !--ind[ne]) q[tt++] = ne;
  }
  return n - res;
}

int main() {
  scanf("%d", &n);
  for (int i = 1; i <= n; i++) {
    int x, m;
    scanf("%d%d", &x, &m);
    // 这句话是必要的,g含有x这个key说明x是有摄像头的
    g.insert({x, {}});
    for (int j = 1; j <= m; j++) {
      int y;
      scanf("%d", &y);
      g[x].push_back(y);
    }
  }
  for (auto &[k, v] : g)
    for (int x : v)
      if (g.count(x)) ind[x]++;

  int res = topsort();
  if (!res)
    puts("YES");
  else
    printf("%d\n", res);
}

时空复杂度 O ( n + m ) O(n+m) O(n+m)

  • 18
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值