列表

详情


MT18. 重要节点

描述

给出一张有向图 G(V,E) ,所有的边都是有向边,对于图上的一个点 v ,从 v 出发可以到达的点的集合记为 S,特别地, v ∈ Sv,再定义一个点的集合 Tv:从Tv中的任意一个点出发,可以到达点 v ,特别地,v∈Tv简而言之,Sv是 v 能到的点的集合,而 T是能到 v 的点的集合。
对于一个点 v ,如果 Tv中的点数严格大于 Sv 中的点数,那么 v 就是一个重要节点,输入一张图,输出图中重要节点的个数

数据范围:

输入描述

第一行输入两个数 n,m ,分别表示点数和边数。 接下来 m 行,每行两个数 u , v 。表示一条从 u 到 v 的有向边,输入中可能存在重边和自环。

输出描述

输出一个数,重要节点的个数

示例1

输入:

4 3
2 1
3 1
1 4

输出:

2

说明:

样例解释:重要节点是1,4。

原站题解

C++14 解法, 执行用时: 6ms, 内存消耗: 632KB, 提交时间: 2020-09-13

#include<iostream>
#include<vector>
#include<queue>
using namespace std;

int main(){
    int n,m,u,v,cnt;
    while(cin>>n>>m){
        vector<vector<int>>g(n+1,vector<int>());
        vector<vector<bool>>vis(n+1,vector<bool>(n+1,false));
        for(int i=0;i<m;++i){
            cin>>u>>v;
            g[u].push_back(v);
        }
        vector<int>in(n+1),out(n+1);
        queue<int>q;
        for(int i=1;i<=n;++i){
            q.push(i);
            vis[i][i]=true;
            while(q.size()){
                int u=q.front();
                q.pop();
                for(int &v:g[u]){
                    if(!vis[i][v]){
                        vis[i][v]=true;
                        out[i]++;
                        in[v]++;
                        q.push(v);
                    }
                }
            }
        }
        cnt=0;
        for(int i=1;i<=n;++i){
            cnt+=(in[i]>out[i]);
        }
        cout<<cnt<<endl;
    }
}

C++14 解法, 执行用时: 6ms, 内存消耗: 1400KB, 提交时间: 2020-09-10

#include <bits/stdc++.h>
using namespace std;

vector<int> G[1001];
bool C[1001][1001] = {false};
int main(){
    int n, m, u, v, cnt=0;
    scanf("%d%d", &n, &m);
    for(int i=0;i<m;i++){
        scanf("%d%d", &u, &v);
        G[u].push_back(v);
    }
    int S[n+1]={0}, T[n+1]={0};
    // memset(S, 0, sizeof(S));
    // memset(T, 0, sizeof(T));
    queue<int> q;
    for(int i=1;i<=n;i++){
        q.push(i);
        C[i][i] = true;
        while(!q.empty()){
            int u = q.front();
            q.pop();
            for(auto &v: G[u]){
                if(!C[i][v]){
                    C[i][v] = true;
                    S[i]++;
                    T[v]++;
                    q.push(v);
                }
            }
        }
    }
    for(int i=1;i<=n;i++)
        if(T[i] > S[i])
            cnt++;
    printf("%d\n", cnt);
    return 0;
}

上一题