题目描述
食品店里有n个摄像头,这种摄像头很笨拙,只能拍摄到固定位置。现有一群胆大妄为的松鼠想要抢劫食品店,为了不让摄像头拍下他们犯罪的证据,他们抢劫前的第一件事就是砸毁这些摄像头。
为了便于砸毁摄像头,松鼠歹徒们把所有摄像头和摄像头能监视到的地方统一编号,一个摄像头能被砸毁的条件是该摄像头所在位置不被其他摄像头监视。
现在你的任务是帮松鼠们计算是否可以砸掉所有摄像头,如不能则输出还没砸掉的摄像头的数量。
输入输出格式
输入格式:
第1行,一个整数n,表示摄像头的个数。
第2到n+1行是摄像头的信息,包括:摄像头的位置x,以及这个摄像头可以监视到的位置数m,之后m个数y是此摄像头可以监视到的位置。(砸了这些摄像头之后自然这些位置就监视不到了)
输出格式:
若可以砸掉所有摄像头则输出“YES”,否则输出还没砸掉的摄像头的数量。
输入输出样例
说明
1<=N<=100
0<=m<=100
0<=x,y<=500
【解法】可以看出,求的是拓扑排序后剩下的点个数.
#include <iostream>
#include <cstdio>
#include <vector>
using namespace std;
#define MAXN 1000
int N, RDg[MAXN], num;
vector<int> G[MAXN], Nodes;
//熟悉一下vector存图
void topology() {
int fpos = -1;
for(int i=0; i < Nodes.size(); i ++) {
if(!RDg[Nodes[i]]) {
RDg[Nodes[i]] = 1e7;
fpos = Nodes[i];
break;
}
}
if(fpos == -1) return;
num ++;
for(int i=0; i < G[fpos].size(); i ++) RDg[G[fpos][i]] --;
G[fpos].clear();
topology();
}
int main() {
int pos, g, tmp;
scanf("%d", &N);
for(int i=1; i<=N; i++) {
scanf("%d %d", &pos, &g);
for(int j=1; j<=g; j++) {
scanf("%d", &tmp);
G[pos].push_back(tmp);
RDg[tmp] ++;
}
Nodes.push_back(pos);
}
topology();
if(num == N) printf("YES\n");
else printf("%d\n", N - num);
return 0;
}