1 条题解

  • 0
    @ 2026-10-18 18:42:08

    G7023 [GESP202609 七级] 必经之路 题解

    知识点:有向图、广度优先搜索、必经点。

    解题思路

    依次禁用每个节点,仍从原图所有入度0的起点BFS;若还能到达原图任一出度0的终点,则该节点不是必经点,否则计入。

    为什么正确

    存在避开禁用节点的起点到终点路径,恰是该节点不属于所有路线的定义;搜索完整判定是否存在这样的反例路径。

    易错点

    起点与终点须使用原图入度、出度定义,删除后新出现的零度点不算新的起终点。

    复杂度

    时间O(n(n+m)),空间O(n+m)。

    参考代码(C++17)

    #include<bits/stdc++.h>
    
    using namespace std;
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(nullptr);
        int n,m;
        cin>>n>>m;
        vector<vector<int>>g(n+1);
        vector<int>in(n+1),out(n+1),ans;
        while(m--) {
            int u,v;
            cin>>u>>v;
            g[u].push_back(v);
            in[v]++;
            out[u]++;
        }
        for(int ban=1;ban<=n;ban++) {
            vector<int>vis(n+1),q;
            for(int u=1;u<=n;u++)if(!in[u]&&u!=ban) {
                q.push_back(u);
                vis[u]=1;
            }
            bool escape=false;
            for(int k=0;k<(int)q.size();k++) {
                int u=q[k];
                if(!out[u]) {
                    escape=true;
                    break;
                }
                for(int v:g[u])if(v!=ban&&!vis[v]) {
                    vis[v]=1;
                    q.push_back(v);
                }
            }
            if(!escape)ans.push_back(ban);
        }
        cout<<ans.size()<<"\n";
        for(int u:ans)cout<<u<<" ";
    }
    

    说明

    本题解为配套教学整理,非官方题解。复杂度按本页参考实现计算,题库使用14个自行生成的测试点。

    • 1

    信息

    ID
    799
    时间
    1000ms
    内存
    512MiB
    难度
    普及
    标签
    递交数
    0
    已通过
    0
    上传者