题解:P5191 [COCI 2009/2010 #6] HOLMES
Left_i_Forever · · 题解
模拟赛时看第三个样例(和本题一样)想到的,比较神秘……
从一个点往回走走到头,可能会有很多个结束的点。反过来,这些点都是拓扑的起点(入度为
令第
对于每一个发生了的
预处理 bitset 优化 DP。
#include <bits/stdc++.h>
using namespace std;
const int N = 1010;
bitset <N> b[N];
vector <int> v[N], v2[N];
int in[N];
int n, m, d;
bool ans[N];
void topsort()
{
queue <int> q;
for (int i = 1; i <= n; i++)
if (!in[i]) b[i][i] = true, q.push (i);
while (q.size ())
{
int u = q.front ();
q.pop ();
for (int j : v[u])
{
in[j]--;
if (!in[j]) q.push (j);
b[j] |= b[u];
}
}
}
int main()
{
// freopen ("detect.in", "r", stdin);
// freopen ("detect.out", "w", stdout);
cin >> n >> m >> d;
for (int i = 1; i <= m; i++)
{
int x, y;
cin >> x >> y;
v[x].push_back (y);
v2[y].push_back (x);
in[y]++;
}
topsort ();
for (int i = 1; i <= d; i++)
{
int x;
cin >> x;
for (int j = 1; j <= n; j++)
{
bitset <N> tep = b[x] & b[j];
if (tep == b[x]) ans[j] = true;
}
}
for (int i = 1; i <= n; i++)
if (ans[i]) cout << i << " ";
puts ("");
return 0;
}