题解:P5954 [JSOI2013] 侦探 JYY
YingDragon_wjq · · 题解
注意到题目中的线索具有传递性,并且整个图是一个 DAG,任意事件不会通过线索导致自身发生。这提示我们可以用拓扑排序来处理事件之间的因果关系。
考虑一个事件在什么情况下必然发生。如果某个已知发生的事件
注意到入度为
由于
对于每个已知发生的事件
综上,我们首先找出所有入度为
拓扑排序配合 bitset 传递源头信息的复杂度为
细节详见代码。
#include<bits/stdc++.h>
#define N 1005
#define endl '\n'
using namespace std;
int n,m,d,in[N];
vector<int> e[N],vec,ans;
bitset<N> s[N];
signed main()
{
scanf("%d%d%d",&n,&m,&d);
for(int i=1;i<=m;i++){
int u,v;
scanf("%d%d",&u,&v);
e[u].push_back(v);
in[v]++;
}
queue<int> q;
for(int i=1;i<=n;i++){
if(in[i]==0){
s[i].set(i);
q.push(i);
}
}
while(q.size()){
int u=q.front();
q.pop();
for(int v:e[u]){
s[v]|=s[u];
if(--in[v]==0) q.push(v);
}
}
for(int i=1;i<=d;i++){
int x;
scanf("%d",&x);
vec.push_back(x);
}
for(int i=1;i<=n;i++){
bool f=0;
for(int tmp:vec){
if((s[tmp]&~s[i])==0){
f=1;
break;
}
}
if(f) ans.push_back(i);
}
for(int res:ans){
printf("%d ",res);
}
return 0;
}