1 条题解

  • 0
    @ 2026-8-27 15:13:58

    注意到题目中的线索具有传递性,并且整个图是一个 DAG,任意事件不会通过线索导致自身发生。这提示我们可以用拓扑排序来处理事件之间的因果关系。

    考虑一个事件在什么情况下必然发生。如果某个已知发生的事件 dd,它的所有“源头”也都能导致 vv 发生,那么 vv 就必然发生。因为 dd 的发生意味着它的某个源头发生了,而这个源头同样会导致 vv。因此我们只需要关注每个事件能被哪些源头事件到达。

    注意到入度为 00 的事件不可能被其他事件导致,它们就是因果链的起点,也就是我们所说的源头。对于每个事件 vv,考虑维护 s(v)s(v) 表示所有能到达 vv 的源头集合。在拓扑排序的过程中,当我们从 uu 走到 vv 时,将 s(u)s(u) 合并到 s(v)s(v) 中,这样最终每个点的 ss 就包含了所有能导致它发生的源头。

    由于 N1000N \leq 1000,考虑用 bitset 来存储源头集合,每次合并是 O(Nw)O( \frac{N}{w}) 的,完全可行。

    对于每个已知发生的事件 dddd 的发生意味着 s(d)s(d) 中至少有一个源头发生了。现在对于一个待判断的事件 vv,如果存在某个已知事件 dd,使得 s(d)s(v)s(d) \subseteq s(v),即所有能导致 dd 的源头也都能导致 vv,那么无论 s(d)s(d) 中哪个源头发生,都必然会导致 vv 发生,因此 vv 一定发生了。反之,如果对于每个 dd 都有 s(d)⊈s(v)s(d) \not\subseteq s(v),那就无法确定 vv 一定发生。

    综上,我们首先找出所有入度为 00 的源头并编号,通过拓扑排序用 bitset 传递源头信息,最后对每个事件 vv 检查是否存在已知事件 dd 满足 s(d)s(d)s(v)s(v) 的子集,即可得到所有必然发生的事件。

    拓扑排序配合 bitset 传递源头信息的复杂度为 O(M+N2w)O(M + \frac{N^2}{w}),最终判断的复杂度为 O(DN2w)O(\frac{DN^2}{w}),在 N1000N \leq 1000 时足以通过。

    细节详见代码。

    #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;
    }
    
    • 1

    信息

    ID
    6143
    时间
    1000ms
    内存
    128MiB
    难度
    10
    标签
    递交数
    1
    已通过
    1
    上传者