注意细节!
我一开始没有分清摄像头和区域,结果都视为一谈。结果只有10分。。。
松鼠敲摄像头的顺序就是拓扑序。
为了方便起见,把区域也视为结点,然后做toposort。
最后能删除多少个摄像头就有多少个摄像头被敲,拿总数\(n\)来减掉这个就是答案。
代码:(我打成嗲吗)
#include<cstdio>
#include<queue>
#include<algorithm>
const int maxn = 505;
bool G[maxn][maxn];
bool vis[maxn];
int minv = maxn, maxv;
int n;
int a[maxn];
int indegree[maxn];
int pos;
int cnt;
bool camera[maxn];
int main()
{
scanf("%d", &n);
for(int i = 1; i <= n; i++)
{
int x, m, y; scanf("%d%d", &x, &m);
vis[x] = true;
camera[x] = true;
minv = std::min(minv, x);
maxv = std::max(maxv, x);
while(m--)
{
scanf("%d", &y);
G[x][y] = true;
vis[y] = true;
minv = std::min(minv, y);
maxv = std::max(maxv, y);
indegree[y]++;
}
}
std::queue<int> q;
for(int i = minv; i <= maxv; i++)
{
if(vis[i])
{
cnt++;
if(indegree[i] == 0) q.push(i);
}
}
while(!q.empty())
{
int u = q.front(); q.pop();
a[++pos] = u;
for(int v = minv; v <= maxv; v++)
{
if(!G[u][v]) continue;
indegree[v]--;
if(indegree[v] == 0) q.push(v);
}
}
int ans = n;
for(int i = 1; i <= pos; i++)
{
if(camera[a[i]]) ans--;
}
if(ans) printf("%d\n", ans);
else printf("YES\n");
return 0;
}