P2712 摄像头

注意细节!


我一开始没有分清摄像头和区域,结果都视为一谈。结果只有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;
}

猜你喜欢

转载自www.cnblogs.com/Garen-Wang/p/9391553.html