SW练习_ P1137 旅行计划_拓扑排序

提交大法好

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();
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值