解题思路
这是一个图论问题,需要找出重要节点的数量。重要节点的定义是:
- 对于节点
,定义
为从
出发可以到达的点的集合(包括
自身)
- 定义
为能到达
的点的集合(包括
自身)
- 如果
中的点数严格大于
中的点数,则
是重要节点
解决方案:
- 对每个点
进行 BFS,找出从
能到达的所有点(构建
)
- 同时统计每个点能被多少个点到达(构建
)
- 最后比较每个点的入度和出度,入度大于出度的点即为重要节点
代码
#include <iostream>
#include <vector>
#include <queue>
using namespace std;
int main() {
int n, m, u, v;
while(cin >> n >> m) {
// 建图
vector<vector<int>> g(n+1);
for(int i = 0; i < m; ++i) {
cin >> u >> v;
g[u].push_back(v);
}
// 计算每个点的可达性
vector<vector<bool>> vis(n+1, vector<bool>(n+1, false));
vector<int> in(n+1), out(n+1);
// 对每个点进行BFS
for(int i = 1; i <= n; ++i) {
queue<int> q;
q.push(i);
vis[i][i] = true;
while(!q.empty()) {
int curr = q.front();
q.pop();
for(int& next : g[curr]) {
if(!vis[i][next]) {
vis[i][next] = true;
out[i]++; // i能到达的点数
in[next]++; // 能到达next的点数
q.push(next);
}
}
}
}
// 统计重要节点
int cnt = 0;
for(int i = 1; i <= n; ++i) {
if(in[i] > out[i]) cnt++;
}
cout << cnt << endl;
}
return 0;
}
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
while(sc.hasNext()) {
int n = sc.nextInt();
int m = sc.nextInt();
// 建图
List<List<Integer>> g = new ArrayList<>(n + 1);
for(int i = 0; i <= n; i++) {
g.add(new ArrayList<>());
}
for(int i = 0; i < m; i++) {
int u = sc.nextInt();
int v = sc.nextInt();
g.get(u).add(v);
}
// 计算每个点的可达性
boolean[][] vis = new boolean[n + 1][n + 1];
int[] in = new int[n + 1];
int[] out = new int[n + 1];
// 对每个点进行BFS
for(int i = 1; i <= n; i++) {
Queue<Integer> q = new LinkedList<>();
q.offer(i);
vis[i][i] = true;
while(!q.isEmpty()) {
int curr = q.poll();
for(int next : g.get(curr)) {
if(!vis[i][next]) {
vis[i][next] = true;
out[i]++;
in[next]++;
q.offer(next);
}
}
}
}
// 统计重要节点
int cnt = 0;
for(int i = 1; i <= n; i++) {
if(in[i] > out[i]) cnt++;
}
System.out.println(cnt);
}
}
}
from collections import deque
def solve():
while True:
try:
n, m = map(int, input().split())
# 建图
g = [[] for _ in range(n + 1)]
for _ in range(m):
u, v = map(int, input().split())
g[u].append(v)
# 计算每个点的可达性
vis = [[False] * (n + 1) for _ in range(n + 1)]
in_deg = [0] * (n + 1)
out_deg = [0] * (n + 1)
# 对每个点进行BFS
for i in range(1, n + 1):
q = deque([i])
vis[i][i] = True
while q:
curr = q.popleft()
for next_node in g[curr]:
if not vis[i][next_node]:
vis[i][next_node] = True
out_deg[i] += 1
in_deg[next_node] += 1
q.append(next_node)
# 统计重要节点
cnt = sum(1 for i in range(1, n + 1) if in_deg[i] > out_deg[i])
print(cnt)
except EOFError:
break
solve()
算法及复杂度
- 算法:BFS(广度优先搜索)
- 时间复杂度:
- 对每个点都需要进行一次BFS
- 空间复杂度:
- 需要存储可达性矩阵