提交大法好
https://www.luogu.com.cn/record/35650074
package info.frady.luogu;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.*;
public class P1137 {
static LinkedList<Integer> list=new LinkedList();//用来存没有入度的点
static int[] dis;//距离
static int[] in;//入度
static int[] out;//出度
static List<Integer>[] f;//f[i][j]表示i的第j个出度
public static void main(String[] args) throws Exception{
BufferedReader reader=new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st=new StringTokenizer(reader.readLine());
int N=Integer.parseInt(st.nextToken());//城市的个数
int M=Integer.parseInt(st.nextToken());//道路的个数
dis=new int[N+1];
in=new int[N+1];
out=new int[N+1];
f=new ArrayList[N+1];
for (int i = 0; i <f.length ; i++) {
f[i]=new ArrayList<Integer>();
f[i].add(0);
}
for (int i = 0; i <M ; i++) {
st=new StringTokenizer(reader.readLine());
int start=Integer.parseInt(st.nextToken());
int end=Integer.parseInt(st.nextToken());
out[start]++;
in[end]++;
f[start].add(end);
}
for (int i = 1; i <=N ; i++) {
if(in[i]==0){//找到入度为0的节点
list.add(i);
dis[i]=1;
}
}
while(!list.isEmpty()){
int c=list.poll();//取出当前节点
for (int i = 1; i <=out[c] ; i++) {//这个点的连接节点入度-1
in[f[c].get(i)]--;
if(in[f[c].get(i)]==0){//如果减完后,这个点入度为0了
list.add(f[c].get(i));
dis[f[c].get(i)]=dis[c]+1;//子节点的入度=前驱节点的入度+1
}
}
}
for (int i = 1; i <=N ; i++) {
System.out.println(dis[i]);
}
reader.close();
}
}
以下是一个临接矩阵保存的,当然只能过一部分用例,但是方便理解
package info.frady.luogu;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.*;
public class P1137Arr {
static LinkedList<Integer> list=new LinkedList();//用来存没有入度的点
static int[] dis;//距离
static int[] in;//入度
static int[] out;//出度
static int[][] f;//f[i][j]表示i的第j个出度
public static void main(String[] args) throws Exception{
BufferedReader reader=new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st=new StringTokenizer(reader.readLine());
int N=Integer.parseInt(st.nextToken());//城市的个数
int M=Integer.parseInt(st.nextToken());//道路的个数
dis=new int[N+1];
in=new int[N+1];
out=new int[N+1];
f=new int[N+1][N+1];
for (int i = 0; i <M ; i++) {
st=new StringTokenizer(reader.readLine());
int start=Integer.parseInt(st.nextToken());
int end=Integer.parseInt(st.nextToken());
out[start]++;
in[end]++;
f[start][out[start]]=end;
}
for (int i = 1; i <=N ; i++) {
if(in[i]==0){//找到入度为0的节点
list.add(i);
dis[i]=1;
}
}
while(!list.isEmpty()){
int c=list.poll();//取出当前节点
for (int i = 1; i <=out[c] ; i++) {//这个点的连接节点入度-1
in[f[c][i]]--;
if(in[f[c][i]]==0){//如果减完后,这个点入度为0了
list.add(f[c][i]);
dis[f[c][i]]=dis[c]+1;//子节点的入度=前驱节点的入度+1
}
}
}
for (int i = 1; i <=N ; i++) {
System.out.println(dis[i]);
}
reader.close();
}
}