给出一张有向图 G(V,E) ,所有的边都是有向边,对于图上的一个点 v ,从 v 出发可以到达的点的集合记为 Sv ,特别地, v ∈ Sv,再定义一个点的集合 Tv:从Tv中的任意一个点出发,可以到达点 v ,特别地,v∈Tv简而言之,Sv是 v 能到的点的集合,而 Tv 是能到 v 的点的集合。
对于一个点 v ,如果 Tv中的点数严格大于 Sv 中的点数,那么 v 就是一个重要节点,输入一张图,输出图中重要节点的个数
数据范围:
, 
第一行输入两个数 n,m ,分别表示点数和边数。 接下来 m 行,每行两个数 u , v 。表示一条从 u 到 v 的有向边,输入中可能存在重边和自环。
输出一个数,重要节点的个数
4 3 2 1 3 1 1 4
2
样例解释:重要节点是1,4。
#include <bits/stdc++.h>
using namespace std;
int main(){
int n, m, u, v, cnt=0;
scanf("%d%d", &n, &m);
vector<int> G[n+1];
bool C[n+1][n+1] = {false};
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};
queue<int> q;
for(int i=1;i<=n;i++){
q.push(i);
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;
} #include <bits/stdc++.h>
using namespace std;
const int AX = 1e3 + 666 ;
int vis[AX] ;
vector<int>G[5][AX] ;
int ans[5] ;
void dfs( int x , int id ) {
vis[x] = 1 ;
ans[id] ++ ;
for( int i = 0 ; i < G[id][x].size() ; i++ ) {
int y = G[id][x][i] ;
if( !vis[y] ) dfs( y , id ) ;
}
}
int main() {
int n , m ;
scanf("%d%d",&n,&m);
int x , y ;
while( m-- ) {
scanf("%d%d",&x,&y);
if( x == y ) continue ;
G[0][x].push_back(y) ;
G[1][y].push_back(x) ;
}
int res = 0 ;
for( int i = 1 ; i <= n ; i++ ) {
ans[0] = 0 ;
ans[1] = 0 ;
memset( vis , 0 , sizeof(vis) ) ;
dfs( i , 0 ) ;
memset( vis , 0 , sizeof(vis) ) ;
dfs( i , 1 ) ;
if( ans[1] > ans[0] ) res ++ ;
}
printf("%d\n",res);
return 0 ;
} import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.LinkedList;
/**
* @author wylu
*/
public class Main {
//arrive[i][j]为true表示从i可以到达j, false则不能
static boolean[][] arrive;
static int[] sv;
static int[] tv;
static ArrayList<Integer>[] graph;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String[] strs = br.readLine().split(" ");
int n = Integer.parseInt(strs[0]), m = Integer.parseInt(strs[1]);
arrive = new boolean[n + 1][n + 1];
sv = new int[n + 1];
tv = new int[n + 1];
graph = new ArrayList[n + 1];
for (int i = 1; i <= n; i++) graph[i] = new ArrayList<>();
for (int i = 0; i < m; i++) {
strs = br.readLine().split(" ");
int u = Integer.parseInt(strs[0]), v = Integer.parseInt(strs[1]);
graph[u].add(v);
}
for (int i = 1; i <= n; i++) bfs(i);
//根据arrive数组计算每个点能达到的点数和能达到每个点的点数
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
if (arrive[i][j]) {
sv[i]++;
tv[j]++;
}
}
}
int res = 0;
for (int i = 1; i <= n; i++) {
if (tv[i] > sv[i]) res++;
}
System.out.println(res);
}
//找出i这个点所能到达的所有点并在arrive数组中进行标记
private static void bfs(int i) {
LinkedList<Integer> queue = new LinkedList<>();
queue.offer(i);
arrive[i][i] = true;
while (!queue.isEmpty()) {
int cur = queue.poll();
for (Integer e : graph[cur]) {
if (!arrive[i][e]) {
arrive[i][e] = true;
queue.offer(e);
}
}
}
}
}
n, m = map(int, input().split())
ds, dt = {}, {} # ds,dt分别记录正向图,反向图
for i in range(1, n+1):
ds[i], dt[i] = set([i]), set([i])
for i in range(m):
x, y = map(int, input().split())
ds[x].add(y)
dt[y].add(x)
def bfs(x,d): # 使用bfs
res = 0
q = [x]
visited = [False]*(n+1)
visited[x] = True
while q:
cur = q.pop(0)
res += 1
for nxt in d[cur]:
if not visited[nxt]:
visited[nxt] = True
q.append(nxt)
return res
cnt = 0
for i in range(1,n+1):
if bfs(i,ds) < bfs(i,dt): cnt += 1
print(cnt) #include<iostream>
#include<vector>
using namespace std;
int test(vector<vector<int> >side,int n,int m)
{
int ans = 0;
if (n == 1 ) return ans;
//1.建立 临近表
vector<vector<int> >table_in(n + 1, vector<int>()); //入度表
vector<vector<int> >table_out(n + 1, vector<int>());//出度表
for (int i = 0; i < m; i++)
{
table_out[side[i][0]].push_back(side[i][1]);
table_in[side[i][1]].push_back(side[i][0]);
}
//2.统计个数
for (int i = 1; i < n + 1; i++)
{
if (table_in[i].size() > table_out[i].size())
ans++;
//cout << table_in[i].size() << "-" << table_out[i].size() << endl;
}
return ans;
}
int main() {
//input
int n, m, ans= 0 ;
cin >> n >> m;
vector<vector<int> > side(m+1, vector<int>(2));
for (int i = 0; i < m; i++)
{
cin >> side[i][0] >> side[i][1];
}
//系统函数
ans = test(side, n, m);
//output,输出重要节点个数(先确定哪些是重要节点),入度大于出度就是重要节点
cout << ans << endl;
return 0;
} 过程简洁明了,自己IDE可以跑,测试就出现问题,也不哪里出现问题暴力
import java.util.*;
public class Main {
static int bfs(List<Set<Integer>> g, int n, int x) {
LinkedList<Integer> q = new LinkedList<>();
boolean used[] = new boolean[n+1];
q.offer(x);
int res = 1;
while(!q.isEmpty()) {
int cur = q.poll();
for(int item : g.get(cur)) {
if(used[item] == false) {
res ++;
q.offer(item);
used[item] = true;
}
}
}
return res;
}
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
int n = sc.nextInt(), m = sc.nextInt();
List<Set<Integer>> g = new ArrayList<>(); // a -> b
List<Set<Integer>> g2 = new ArrayList<>(); // b -> a
for(int i=0; i <= n; i++) {
g.add(new HashSet<>());
g2.add(new HashSet<>());
}
for(int i=0; i < m; i++) {
int a = sc.nextInt(), b = sc.nextInt();
if(a != b) {
g.get(a).add(b);
g2.get(b).add(a);
}
}
int res = 0;
for(int i=1; i <= n; i++) {
int s = bfs(g, n, i);
int t = bfs(g2, n, i);
if(s < t) res++;
}
System.out.println(res);
}
}
#include <stdio.h>
#define MAXN 1010
int n,m;
int map[MAXN][MAXN];
int T[MAXN];
int S[MAXN];
int main()
{
int i,j,k,x,y,t,s,sum;
scanf("%d%d",&n,&m);
for(i=0;i<m && scanf("%d%d",&x,&y)!=EOF;i++)
map[x][y] = 1;
for(k=1;k<=n;k++)
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
if(map[i][k]&map[k][j])
map[i][j] = 1;
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
if(map[i][j])
{
T[j]++;
S[i]++;
}
for(sum=0,i=1;i<=n;i++)
sum += T[i]>S[i];
printf("%d\n",sum);
return 0;
} import sys
from collections import deque
if __name__ == "__main__":
line = raw_input()
lines = line.split()
n = int(lines[0])
m = int(lines[1])
edges = []
for i in range(m):
line = raw_input()
lines = line.split()
tmp = [int(lines[0]),int(lines[1])]
if tmp not in edges and tmp[0]!=tmp[1]:
edges.append(tmp)
adjList = {}
for idx in range(1,n+1):
adjList[idx] = []
for i in range(len(edges)):
b = edges[i]
adjList[b[0]].append(b[1])
reach = {}
for idx in range(1,n+1):
reach[idx] = [idx]
for idx in range(1,n+1):
stack = deque([])
visited = [0 for i in range(n+1)]
stack.append(idx)
visited[idx] = 1
while True:
tmp = stack.popleft()
for node in adjList[tmp]:
if visited[node] == 0:
visited[node] = 1
stack.append(node)
reach[idx].append(node)
if len(stack) == 0:
break
x = [0 for i in range(n+1)]
y = [0 for i in range(n+1)]
for idx in range(1,n+1):
x[idx] = len(reach[idx])
for idx in range(1,n+1):
times = 0
for jdx in range(1,n+1):
if idx in reach[jdx]:
times += 1
y[idx] = times
count = 0
for idx in range(1,n+1):
if y[idx]>x[idx]:
count += 1
print count
70% 通过,不知道卡在哪里啦,很奇怪,哪位大神能解答一下?