摄像头

来源:互联网 发布:牛黄解毒片 知乎 编辑:程序博客网 时间:2024/04/27 17:22

QAQ
看一下题面,发现只有没有摄像头监视的摄像头才可以砸掉,妥妥的拓扑排序
每次去找入度为0的摄像头,再进行删除它的邻接点的入度操作,直到没有入度为0的摄像头或者是全部砸掉
注意一个小坑:那就是其实摄像头的编号并不是1-n(虽然样例是)
那么我们记录最大的编号,从1-Max扫,使用F数组标记摄像头的位置,即可AC。

#include <cstdio>#include <iostream>#include <cmath>#include <cstring>#include <string>using namespace std;int r[99999];int head[99999],net[99999],to[99999];int cnt;int f[99999];void add(int x,int y){    to[++cnt]=y;    net[cnt]=head[x];    head[x]=cnt;}int work(int n,int maxf){    int ans=0;    for(;;)    {        int t=0;        for(int i=1;i<=maxf;i++)         if(r[i]==0&&f[i]==1)           {            ans++;            t=i;            break;          }        if(!t) return ans;        for(int i=head[t];i;i=net[i])         r[to[i]]--;        f[t]=0;    }} int main(){    int maxf=0;    int n;    scanf("%d",&n);    for(int i=1;i<=n;i++)     {        int x,y;        scanf("%d%d",&x,&y);        f[x]=1;        maxf=max(maxf,x);        for(int j=1;j<=y;j++)         {            int z;            scanf("%d",&z);            maxf=max(maxf,z);            add(x,z);            r[z]++;         }     }     int ans=work(n,maxf);     if(ans==n) printf("YES");     else printf("%d",n-ans);     return 0;}