• JAVA 图论


    拓扑排序

    210. 课程表 II

    难度中等

    现在你总共有 numCourses 门课需要选,记为 0 到 numCourses - 1。给你一个数组 prerequisites ,其中 prerequisites[i] = [ai, bi] ,表示在选修课程 ai 前 必须 先选修 bi 。

    • 例如,想要学习课程 0 ,你需要先完成课程 1 ,我们用一个匹配来表示:[0,1] 。

    返回你为了学完所有课程所安排的学习顺序。可能会有多个正确的顺序,你只要返回 任意一种 就可以了。如果不可能完成所有课程,返回 一个空数组 。

     基于BFS实现  只能输出一种

    class Solution {
        List<List<Integer>>edge = new  ArrayList<List<Integer>>();
        int res[];
        int in[];
        public int[] findOrder(int numCourses, int[][] prerequisites) {
                        res  =new int[numCourses];
                        in  =new int[numCourses];
                      for(int i=0;i<numCourses;i++)  edge.add(new ArrayList<Integer>());
                      for(int a[]:prerequisites) {
                           edge.get(a[1]).add(a[0]);
                           in[a[0]]++;
                      }
                      Queue<Integer>que =  new LinkedList();
                      for(int i=0;i<numCourses;i++){
                          if(in[i]==0)  que.offer(i);
                      }
                      int id  =0;
                      while(!que.isEmpty()){
                          int tmp   = que.poll();
                          res[id++]  =tmp;
                          for(int z:edge.get(tmp)){
                              in[z]--;
                              if(in[z]==0)  que.offer(z);
                          }
                      }
                      if(id!=numCourses)  return new int[0];//有环
                      return res;
        }
    }

    N个节点,M条边 

    时空复杂度都为O(M+N)

    针对上述代码进行离散化
            int a_[] = new int[a.length];
            Arrays.sort(a);
            for (int i = 0; i < a.length; i++) {
                a_[i] = Arrays.binarySearch(a, a[i]);
                map.put(a[i], a_[i]);
            }
    
            int po[][] = { { 3, 1 }, { 4, 3 }, { 5, 4 }, { 2, 4 } };
            int po_[][] = new int[po.length][po[0].length];
            int i = 0;
            for (int x[] : po) {
                po_[i][0] = map.get(x[0]);
                po_[i][1] = map.get(x[1]);
                i++;
            }

    DFS 输出所有拓扑排序

    import java.util.*;
    
    import javax.annotation.processing.SupportedOptions;
    
    public class Main {
    
        static List<List<Integer>> edge = new ArrayList<List<Integer>>();
        static int res[];
        static Map<Integer, Integer> map = new HashMap<>();
        static boolean vis[], viss[][];
        static int n, ans = 0;
        static int a[] = { 1, 2, 3, 4, 5 };
        static int a_[];
    
        public static boolean ok(int i, int cnt) {
            for (int j = 0; j < cnt; j++) {
                if (viss[i][res[j]])
                    return false;
            }
            return true;
        }
    
        public static void dfs(int cnt) {//第cnt个数
            if (cnt == n) {
                ans++;
                for (int i = 0; i < cnt; i++) {
                    System.out.print(res[i] + " ");
                }
                System.out.println(" ");
                return;
            }
            for (int j = 0; j < n; j++) {
                if (!vis[a_[j]] && ok(a_[j], cnt)) {
                    vis[a_[j]] = true;
                    res[cnt] = a_[j];
                    dfs(cnt + 1);
                    vis[a_[j]] = false;
                }
                // if (!vis[a_[j]]) {
                // vis[a_[j]] = true;
                // res[cnt] = a_[j];
                // dfs(cnt + 1);
                // vis[a_[j]] = false;
                // }
            }
        }
    
        public static void main(String[] args) {
    
            n = a.length;
            // 离散化 [0,n-1]
            a_ = new int[n];
            res = new int[n];
            Arrays.sort(a);
            for (int i = 0; i < n; i++) {
                a_[i] = Arrays.binarySearch(a, a[i]);
                map.put(a[i], a_[i]);
            }
            vis = new boolean[n + 1];
            viss = new boolean[n + 1][n + 1];
            int po[][] = { { 3, 1 }, { 4, 3 }, { 5, 4 }, { 2, 4 } };
            int po_[][] = new int[po.length][po[0].length];
            int i = 0;
            for (int x[] : po) {
                po_[i][0] = map.get(x[0]);
                po_[i][1] = map.get(x[1]);
                viss[po_[i][1]][po_[i][0]] = true;
                i++;
            }
            dfs(0);
        }
    
    }

    一个公司准备组织一场会议,邀请名单上有 n 位员工。公司准备了一张 圆形 的桌子,可以坐下 任意数目 的员工。

    员工编号为 0 到 n - 1 。每位员工都有一位 喜欢 的员工,每位员工 当且仅当 他被安排在喜欢员工的旁边,他才会参加会议。每位员工喜欢的员工 不会 是他自己。

    给你一个下标从 0 开始的整数数组 favorite ,其中 favorite[i] 表示第 i 位员工喜欢的员工。请你返回参加会议的 最多员工数目 。

     

    按照题意,多个人围成一个环,环外可能枝连其他节点
    (1)环内只有2个节点
         1 和2坐在一起,5只能在2的右边,3,4,6只能在1的左边。3,4不能同时出现
         这种情况,1为根的最长链+2为根的最长链
     
     (2)环内有大于等于3个节点
         7 8 9 围成一个环,10不能加入环,因为加入10会破坏原来的结构
    第一种情况,可以并接。第二种情况,只能取一个环  因为只有一个桌子

     结果为(1)(2)的最大值

    class Solution {   
        public int maximumInvitations(int[] favorite) {
            int n  =favorite.length;
            int f[]  =new int[n+1];
            int in[]  =new int [n+1];
            int u,v,cnt;
            for(int x:favorite){
                in[x]++;
            }      
            Arrays.fill(f,1);
            Queue<Integer>que =new LinkedList();
            for(int i =0;i<n;i++) {
                if(in[i]==0) que.offer(i);
            }
            //去树枝
            while(!que.isEmpty()){
                 u  =que.poll();
                 v  =favorite[u];
                f[v]  =Math.max(f[v],f[u]+1);//f[v]:v为根的最长链长度
                in[v]--;
                if(in[v]==0)  que.offer(v);
            }
            int two=0,three=0;
            for(int j=0;j<n;j++){
                if(in[j]==1){
                    in[j]--;
                         u  =favorite[j];
                         if(favorite[u]==j){//2个点的环
                                  two+=(f[j]+f[u]);
                                   in[u]--;
                         }
                         else{//大于等于3个点的环
                            cnt =1;
                            while(u!=j){
                                cnt++;
                                in[u]--;
                                u = favorite[u];                         
                            }
                            three  =Math.max(three,cnt);
                         }
                }
    
            }
    return Math.max(three,two);
             
        }
    }
  • 相关阅读:
    React(七)独立组件间的共享Mixins
    React(六)Props属性
    React(五)State属性
    React(四)组件生命周期
    React(三)JSX内置表达式
    Python(一)缺点
    Vue(二十六)父子组件通信
    React(二)组件
    React(一)使用脚手架创建React项目
    Vue(二十五)打包后路径报错问题
  • 原文地址:https://www.cnblogs.com/tingtin/p/15836077.html
Copyright © 2020-2023  润新知