CF1019C

题意

\(n\) 个点 \(m\) 条边有向图。
问求出任意一个点集 \(S\) 满足 \(\forall\ u,\ v\ \in\ S,\ d(u,\ v)\ >\ 1\ or\ u\ =\ v\)\(\forall\ u\ \notin\ S,\ \exists\ v\ \in\ S,\ d(v,\ u)\ \leq\ 2\)

\(1\ \leq\ n,\ m\ \leq\ 10^6\)

做法

考虑归纳法,取出点 \(u\) 以及 \(u\) 连向的所有点,将这些点删去后的答案设为 \(T\)。如果 \(T\) 中有点 \(v\) 使得 \(v,\ u\) 有边相连,则无需选择 \(u\) 否则选 \(u\)
时间复杂度 \(O(n\ +\ m)\)

代码

#include <bits/stdc++.h>

#ifdef DEBUG
#define debug(...) fprintf(stderr, __VA_ARGS__)
#else
#define debug(...)
#endif

#ifdef __WIN32
#define LLFORMAT "I64"
#define Rand() ((rand() << 15) + rand())
#else
#define LLFORMAT "ll"
#define Rand() (rand())
#endif

using namespace std;

const int maxn = 1e6 + 10;

template<int input_SZ, int output_SZ> struct IO {
    char s[input_SZ], t[output_SZ], *a, *b;

    IO() { fread(s, 1, input_SZ, stdin); a = s; b = t; }
    ~IO() { fwrite(t, 1, b - t, stdout); }

    char nextchar(char c) {
        return *a++;
    }

    int nextint() {
        while(*a != '-' && (*a < '0' || *a > '9')) ++a;
        bool flag = 0; int x = 0;
        if(*a == '-') ++a, flag = 1;
        while(*a >= '0' && *a <= '9') x = x * 10 + *a++ - '0';
        if(flag) x = -x;
        return x;
    }

    long long nextll() {
        while(*a != '-' && (*a < '0' || *a > '9')) ++a;
        bool flag = 0; long long x = 0;
        if(*a == '-') ++a, flag = 1;
        while(*a >= '0' && *a <= '9') x = x * 10 + *a++ - '0';
        if(flag) x = -x;
        return x;
    }

    void outchar(char c) {
        *b++ = c;
        if(b - t > output_SZ - 25) { fwrite(t, 1, b - t, stdout); b = t; }
        return;
    }

    template<typename T> void outnum(T x) {
        if(!x) { *b++ = '0'; return; }
        if(x < 0) *b++ = '-', x = -x;
        static char s[20], *a;
        a = s;
        while(x) {
            T y = x / 10;
            *a++ = x - y * 10 + '0';
            x = y;
        }
        while(a != s) *b++ = *--a;
        if(b - t > output_SZ - 25) { fwrite(t, 1, b - t, stdout); b = t; }
        return;
    }

    template<typename T> void outnum(T x, char c) {
        return outnum(x), outchar(c);
    }
};

IO<(1 << 24) | 10, (1 << 23) | 10> io;

int n, m, f[maxn], stk[maxn], top;
vector<int> g[maxn], ans;

void upd(int u) { for (int v: g[u]) f[v] = 2; }

int main() {
	n = io.nextint(); m = io.nextint();
	for (int i = 0; i < m; ++i) {
		int u = io.nextint(), v = io.nextint();
		g[u].push_back(v);
	}
	for (int u = 1; u <= n; ++u) {
		if(!f[u]) {
			stk[top++] = u;
			f[u] = 1;
			for (int v: g[u]) f[v] = 1;
		}
	}
	int u = stk[--top]; f[u] = 0; upd(u); ans.push_back(u);
	while(top--) {
		int u = stk[top];
		if(f[u] == 1) f[u] = 0, upd(u), ans.push_back(u);
	}
	io.outnum(ans.size(), '\n');
	for (int u: ans) io.outnum(u, ' ');
	return 0;
}
posted @ 2018-08-13 13:17  King_George  阅读(173)  评论(0编辑  收藏  举报