2021-09-10(拓扑排序)

import java.io.*;
import java.util.*;

public class Solution {
    
    

    public static void main(String[] args) throws IOException {
    
    
        for (int i = 0; i <= 100000; i++) adj.add(new LinkedList<>());
        in = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
        int T = nextInt();
        for (int tc = 1; tc <= T; tc++) {
    
    
            readCase();
            work();
            System.out.println("#" + tc + " " + ans);
        }
    }

    static void work() {
    
    
        //找出入度为0的点,从这样的点开始拓扑排序(遍历)
        for (int i = 1; i <= N; i++) {
    
    
            if (inDep[i] == 0) {
    
    
                topQue.add(i);
                cnt[i] = 1;
            }
        }
        long maxV = 0;        //最大深度值
        //拓扑排序(遍历)
        while (!topQue.isEmpty()) {
    
    
            int fm = topQue.poll();
            while (!adj.get(fm).isEmpty()) {
    
    
                int to = adj.get(fm).poll();
                if (cnt[to] < cnt[fm] + 1) {
    
    
                    cnt[to] = cnt[fm] + 1;
                    p[to] = fm;
                    maxV = Math.max(cnt[to], maxV);
                } else if (cnt[to] == cnt[fm] + 1) {
    
    
                    p[to] = Math.max(p[to], fm);
                }
                if (--inDep[to] == 0) topQue.add(to);
            }
        }
        //找出最大深度点
        for (int i = 1; i <= N; i++) {
    
    
            if (cnt[i] == maxV) topQue.add(i);
        }
        //通过每个点的前驱点p[],计算加和,求最大ans
        while (!topQue.isEmpty()) {
    
    
            int nx = topQue.poll();
            long sum = 0;
            while (nx != 0) {
    
    
                sum += nx * cnt[nx];
                nx = p[nx];
            }
            ans = Math.max(sum, ans);
        }
        Arrays.fill(inDep, 0, N + 1, 0);
        Arrays.fill(cnt, 0, N + 1, 0);
    }

    static void readCase() throws IOException {
    
    
        N = nextInt();
        M = nextInt();
        for (int i = 0; i < M; i++) {
    
    
            int a = nextInt();
            int b = nextInt();
            adj.get(b).add(a);
            inDep[a]++;
        }
    }

    static int nextInt() throws IOException {
    
    
        in.nextToken();
        return (int) in.nval;
    }

    static StreamTokenizer in;
    static int N, M;
    static long ans;
    static final int[] inDep = new int[100002];
    static final long[] cnt = new long[100002];
    static final int[] p = new int[100002];
    static final ArrayList<LinkedList<Integer>> adj = new ArrayList<>();
    static final LinkedList<Integer> topQue = new LinkedList<>();
}

猜你喜欢

转载自blog.csdn.net/awp0011/article/details/120229310
今日推荐