P3916 图的遍历
题目描述
给出N个点,M条边的有向图,对于每个点v,求A(v)表示从点v出发,能到达的编号最大的点。
输入格式
第1 行,2 个整数N,M。
接下来MM行,每行2个整数U_i,V_i,表示边(U_i,V_i)。点用1,2,⋯,N编号。
输出格式
N 个整数A*(1),A(2),⋯,A(*N)。
输入输出样例
输入 #1
4 3
1 2
2 4
4 3
输出 #1
4 4 3 4
说明/提示
• 对于60% 的数据,1≤N.M≤10^3;
• 对于100% 的数据,1≤N,M≤10^5。
题解
package p3916;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Arrays;
public class Main {
static int N = 100010;
static int n,m;
static int h[] = new int[N],e[] = new int[N],ne[] = new int[N],idx=0;
static int a[] = new int[N];
static void add(int a,int b) {
e[idx] = b;ne[idx] = h[a];h[a] = idx++;
}
static void dfs(int u,int d) {
if(a[u]!=0) {
return;
}
a[u] = d;
for(int i = h[u];i!=-1;i = ne[i]) {
int j = e[i];
dfs(j,d);
}
return;
}
public static void main(String[] args) throws Exception{
BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
String str[] = bf.readLine().split(" ");
Arrays.fill(h, -1);
n = Integer.parseInt(str[0]);m = Integer.parseInt(str[1]);
while(m-->0) {
str = bf.readLine().split(" ");
int a = Integer.parseInt(str[0]),b = Integer.parseInt(str[1]);
add(b,a);
}
bf.close();
for(int i=n;i>0;i--) {
dfs(i,i);
}
for(int i=1;i<=n;i++) {
System.out.print(a[i]+" ");
}
}
}