「JSOI2013」侦探jyy

「JSOI2013」侦探jyy

传送门

个人感觉我写的复杂度不够优秀啊,但是好像没有别的办法了...

我们枚举每个点,考虑这个点能不能不发生。

首先我们从这个点开始,在反图上面 \(\text{BFS}\) 只要碰到已经发生的点则这个点必须发生。

然后我们再考虑是不是能满足题目要求的点都发生,那么我们就把所有之前那次 \(\text{BFS}\) 没有访问到的入度为零的点都用来在原图上 \(\text{BFS}\) ,如果还是存在一个点不能被满足则这个点也必须发生。

否则可以不发生。

复杂度好像是 \(O(nm)\) 的,但是跑不满所以还是可以过(雾

#include 
#include 
#include 
#define rg register
#define file(x) freopen(x".in", "r", stdin), freopen(x".out", "w", stdout)
using namespace std;
template < class T > inline void read(T& s) {
    s = 0; int f = 0; char c = getchar();
    while ('0' > c || c > '9') f |= c == '-', c = getchar();
    while ('0' <= c && c <= '9') s = s * 10 + c - 48, c = getchar();
    s = f ? -s : s;
}
 
const int _ = 1e3 + 5, __ = 1e5 + 5;
 
int tot, phead[_], rhead[_]; struct Edge { int v, nxt; } edge[__ << 1];
inline void Add_edge(int* head, int u, int v) { edge[++tot] = (Edge) { v, head[u] }, head[u] = tot; }
 
int n, m, k, a[_], ra[_], dgr[_], vis[_];
queue < int > Q;
 
inline void bfs(int x) {
    memset(vis + 1, 0, sizeof (int) * n);
    Q.push(x);
    while (!Q.empty()) {
        int u = Q.front(); Q.pop(), vis[u] = 1;
        for (rg int i = rhead[u]; i; i = edge[i].nxt)
            if (!vis[edge[i].v]) Q.push(edge[i].v);
    }
}
 
inline bool check(int x) {
    bfs(x);
    for (rg int i = 1; i <= k; ++i) if (vis[a[i]]) return 1;
    for (rg int i = 1; i <= n; ++i) if (!dgr[i] && !vis[i]) Q.push(i);
    while (!Q.empty()) {
        int u = Q.front(); Q.pop(), vis[u] = 1;
        for (rg int i = phead[u]; i; i = edge[i].nxt)
            if (!vis[edge[i].v]) Q.push(edge[i].v);
    }
    for (rg int i = 1; i <= k; ++i) if (!vis[a[i]]) return 1;
    return 0;
}
 
int main() {
#ifndef ONLINE_JUDGE
    file("cpp");
#endif
    read(n), read(m), read(k);
    for (rg int u, v, i = 1; i <= m; ++i)
    read(u), read(v), Add_edge(phead, u, v), Add_edge(rhead, v, u), ++dgr[v];
    for (rg int i = 1; i <= k; ++i) read(a[i]), ra[a[i]] = 1;
    for (rg int i = 1; i <= n; ++i) if (ra[i] || check(i)) printf("%d ", i);
    return 0;
}

你可能感兴趣的:(「JSOI2013」侦探jyy)