简单介绍一下拓扑排序把。拓扑排序其实不是一种排序而是一种前后关系的输出。拓扑排序输出序号的规则(拓扑排序的实现),首先我们找到入度为0的点,然后把它输出并删掉,之后把与他直接相连的点的入度减去1,并找到入度为0的点,接着把这个输出并删除。之后把与他相连的点的入度减去1.直到把所有点输出为止。拓扑排序要求点与点之间有前后关系,并且图不能有环。
那么我们来说说它的作用吧
拓扑排序其实可以找到到达一个点共有几种路径。原理就是我们首先找到一个入度为0的点,它前面没有任何其他点,因为入读为0吗。所以它肯定是起点。由于我们在删除这个点时会删除与他直接相连的边,而每一条边都是一条路径,所以我们把起点赋值为1代表从起点开始只有一条路径,之后每删一条边时我们便在这条被删的边的另一个点加上前一个点的路径数。
最后我们输出终点的路径数
下面给出模板并解释
import java.awt.FontFormatException;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.lang.reflect.AnnotatedWildcardType;
import java.math.BigInteger;
import java.net.DatagramPacket;
import java.sql.SQLIntegrityConstraintViolationException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.Map;
import java.util.Objects;
import java.util.PriorityQueue;
import java.util.Scanner;
import java.util.Spliterator.OfPrimitive;
import java.util.function.IntToDoubleFunction;
import java.util.function.LongBinaryOperator;
import java.util.TreeMap;
import java.util.TreeSet;
import javax.management.relation.InvalidRelationTypeException;
import javax.print.attribute.standard.JobMessageFromOperator;
import javax.print.attribute.standard.JobPriority;
import javax.swing.plaf.ColorChooserUI;
import javax.swing.table.TableModel;
import javax.swing.text.TabSet;
import javax.xml.crypto.dsig.spec.DigestMethodParameterSpec;
public class Main {
public static void main(String[] args) throws IOException {
Scanner sc=new Scanner(System.in);
BufferedReader br1=new BufferedReader(new InputStreamReader(System.in));
PrintWriter pw1=new PrintWriter(System.out);
String[] aStrings=br1.readLine().split(" ");
int a=Integer.parseInt(aStrings[0]);
int b=Integer.parseInt(aStrings[1]);
int c;
for(c=1;c<=a;c++) {
al1[c]=new ArrayList<>();
}
for(c=0;c<b;c++) {
String[] bStrings=br1.readLine().split(" ");
int d=Integer.parseInt(bStrings[0]);
int e=Integer.parseInt(bStrings[1]);
in[e]++;
out[d]++;
al1[d].add(e);
}
int d;
for(d=1;d<=a;d++) {
if(in[d]==0) {
cc[d]=1;//找到起点,此题起点与终点不一定只有一个
pq1.offer(d);//把起点放入堆中
}
}
while(pq1.size()!=0) {//当入度为0的点还有时继续删点
int e=pq1.poll();
int f=al1[e].size();//取出与点e直接相连的点
int g;
for(g=0;g<f;g++) {
in[al1[e].get(g)]--;//这个点的入度减一
cc[al1[e].get(g)]=(cc[al1[e].get(g)]+cc[e])%aa;
if(in[al1[e].get(g)]==0) {//入读为0加入
pq1.add(al1[e].get(g));
}
}
}
int answer=0;
for(d=1;d<=a;d++) {
if(out[d]==0) {//找到所有终点累加
answer=(answer+cc[d])%aa;
}
}
System.out.println(answer);
}
public static int aa=80112002;//题目要求取余
public static int bb=10000;//点的最大数量
public static int[] in=new int[bb];//每个点的入度
public static int[] out=new int[bb];//每个点的出度
public static int[] cc=new int[bb];//到达这个点的路径数
public static ArrayList<Integer>[] al1=new ArrayList[bb];//用来存放与这个点直接相连的点
public static PriorityQueue<Integer> pq1=new PriorityQueue<>();//放置入度为0的点
}
P4017 最大食物链计数 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
模板对应的题目