本题主要运用拓扑排序来解题,将每个队伍作为一个节点,如果两个队友有比赛,胜者作为负者的入度。如果负者输于多个队伍,则进行入度加运算,如果出去的是它的入度,则进行入度减一运算,每次取入度为0,切编号小的数。即按顺序遍历所有节点,发现入读为0且未排序的节点。即中止此次遍历,对其进行出栈,处理 并将与其相邻的节点的入度-1.用if(i==n)来做防止图有回路。下面是具体代码实现:(已AC)
<span style="font-size:18px;">import java.util.Scanner;
public class Main{
static int n;
static int m;
static int degre[];//入度数
static int sorted[];//是否排序。0未排,1已排
static int arc[][];//胜负结果数组
static Scanner sc=new Scanner(System.in);
public static void main(String[] args) {
while(sc.hasNext()){
n=sc.nextInt();
m=sc.nextInt();
init();
topoSort();
}
}
private static void topoSort() {
int s=0;//已排序的节点数
while(s<n){
int i=0;
//按顺序遍历所有节点,发现入读为0且未排序的节点。即中止此次遍历,对其进行出栈,处理 并将与其相邻的节点的入度-1.
for(i=0;i<n;i++){
if(degre[i]==0&&sorted[i]==0){
break;
}
}
if(i==n){
System.out.println("图有回路,无解");
return;
}
//对for循环中找的节点i进行处理
sorted[i]=1;
s++;
System.out.print(i+1);
if(s<n){
System.out.print(" ");
}
for(int j=0;j<n;j++){
if(arc[i][j]!=0){
degre[j]--;//把以i节点 为起点 节点j的入度-1;
}
}
}
System.out.println();
}
private static void init() {
//数组初始化
sorted=new int[n];
degre=new int[n];
arc=new int[n][n];
for (int i = 0; i < n; i++) {
sorted[i]=0;
degre[i]=0;
for (int j = 0; j <n; j++) {
arc[i][j]=0;
}
}
//每场比赛胜负的输入
for (int i = 0; i < m; i++) {
int a=sc.nextInt()-1;
int b=sc.nextInt()-1;
if (arc[a][b]==0) {//防护有重复边
arc[a][b]=1;//节点a与节点b有连通
degre[b]++;//节点b的入度+1
}
}
}
}</span>