http://www.lydsy.com/JudgeOnline/problem.php?id=4579
把时间倒过来,只是加点,并查集维护连通块。
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 200003;
struct node {int nxt, to;} E[N << 1];
int a[N], tot = 0, n, m, cnt = 0, point[N], fa[N];
bool mark[N], op[N];
void ins(int u, int v) {
E[++cnt] = (node) {point[u], v}; point[u] = cnt;
}
int find(int x) {return x == fa[x] ? x : fa[x] = find(fa[x]);}
int main() {
scanf("%d%d", &n, &m);
int u, v;
for (int i = 1; i <= m; ++i) {
scanf("%d%d", &u, &v);
ins(u, v); ins(v, u);
}
for (int i = 1; i <= n; ++i) scanf("%d", a + i), fa[i] = i;
for (int i = n; i >= 1; --i) {
mark[a[i]] = true;
++tot;
for (int j = point[a[i]]; j; j = E[j].nxt)
if (mark[E[j].to] && (u = find(E[j].to)) != (v = find(a[i])))
fa[u] = v, --tot;
if (tot == 1)
op[i] = true;
else
op[i] = false;
}
for (int i = 1; i <= n; ++i)
puts(op[i] ? "YES" : "NO");
return 0;
}