• 《算法》第四章部分程序 part 11


    ▶ 书中第四章部分程序,包括在加上自己补充的代码,二分图的判定和染色

    ● 二分图 1

      1 //+-----------------------------------------------------------------------------
      2 // 第四章,二分图
      3 package package01;
      4 
      5 import edu.princeton.cs.algs4.StdOut;
      6 import edu.princeton.cs.algs4.StdRandom;
      7 import edu.princeton.cs.algs4.GraphGenerator;
      8 import edu.princeton.cs.algs4.Graph;
      9 import edu.princeton.cs.algs4.Stack;
     10 
     11 public class class01
     12 {
     13     private boolean isBipartite;
     14     private boolean[] color;            // 顶点染色情况
     15     private boolean[] marked;
     16     private int[] edgeTo;
     17     private Stack<Integer> cycle;       // odd-length cycle
     18 
     19     public class01(Graph G)
     20     {
     21         isBipartite = true;
     22         color = new boolean[G.V()];
     23         marked = new boolean[G.V()];
     24         edgeTo = new int[G.V()];
     25         for (int v = 0; v < G.V(); v++)// 逐顶点深度优先遍历
     26         {
     27             if (!marked[v])
     28             {
     29                 dfs(G, v);
     30             }
     31         }
     32     }
     33 
     34     private void dfs(Graph G, int v)
     35     {
     36         marked[v] = true;
     37         for (int w : G.adj(v))
     38         {
     39             if (cycle != null)                          // 已经有奇数环,停止递归
     40                 return;
     41             if (!marked[w])                             // 正常的标记、染色、继续递归
     42             {
     43                 edgeTo[w] = v;
     44                 color[w] = !color[v];
     45                 dfs(G, w);
     46             }
     47             else if (color[w] == color[v])              // v ~ w 形成了长度为奇数的环
     48             {
     49                 isBipartite = false;
     50                 cycle = new Stack<Integer>();
     51                 for (int x = v; x != w; x = edgeTo[x])  // 把从 v 到 w 的顶点压栈,保存有问题的环部分
     52                     cycle.push(x);
     53                 cycle.push(w);
     54             }
     55         }
     56     }
     57 
     58     public boolean isBipartite()
     59     {
     60         return isBipartite;
     61     }
     62 
     63     public boolean color(int v)
     64     {
     65         if (!isBipartite)
     66             throw new UnsupportedOperationException("
    <color> Graph is not bipartite.
    ");
     67         return color[v];
     68     }
     69 
     70     public Iterable<Integer> oddCycle()
     71     {
     72         return cycle;
     73     }
     74 
     75     public static void main(String[] args)
     76     {
     77         int V1 = Integer.parseInt(args[0]); // 生成 G(V1 + V2, E) 顶点的二分图,再随机添加 F 条边
     78         int V2 = Integer.parseInt(args[1]);
     79         int E = Integer.parseInt(args[2]);
     80         int F = Integer.parseInt(args[3]);
     81 
     82         Graph G = GraphGenerator.bipartite(V1, V2, E);
     83         for (int i = 0; i < F; i++)
     84         {
     85             int v = StdRandom.uniform(V1 + V2);
     86             int w = StdRandom.uniform(V1 + V2);
     87             G.addEdge(v, w);
     88         }
     89         StdOut.println(G);
     90 
     91         class01 b = new class01(G);
     92         if (b.isBipartite())
     93         {
     94             StdOut.println("Graph is bipartite");
     95             for (int v = 0; v < G.V(); v++)
     96                 StdOut.println(v + ": " + b.color(v));
     97         }
     98         else
     99         {
    100             StdOut.print("Graph has an odd-length cycle: ");
    101             for (int x : b.oddCycle())
    102                 StdOut.print(x + " ");
    103             StdOut.println();
    104         }
    105     }
    106 }

    ● 二分图 2

      1 package package01;
      2 
      3 import edu.princeton.cs.algs4.StdOut;
      4 import edu.princeton.cs.algs4.StdRandom;
      5 import edu.princeton.cs.algs4.GraphGenerator;
      6 import edu.princeton.cs.algs4.Graph;
      7 import edu.princeton.cs.algs4.Stack;
      8 import edu.princeton.cs.algs4.Queue;
      9 
     10 public class class01
     11 {
     12     private boolean isBipartite;   // 是否为二分图
     13     private boolean[] color;       // 顶点染色
     14     private boolean[] marked;      
     15     private int[] edgeTo;          
     16     private Queue<Integer> cycle;  // 存储了奇数长度的环(二分图则队列为空)
     17 
     18     public class01(Graph G)
     19     {
     20         isBipartite = true;
     21         color = new boolean[G.V()];
     22         marked = new boolean[G.V()];
     23         edgeTo = new int[G.V()];
     24         for (int v = 0; v < G.V() && isBipartite; v++)
     25         {
     26             if (!marked[v])
     27                 bfs(G, v);                          // 广度优先遍历
     28         }
     29     }
     30 
     31     private void bfs(Graph G, int s)
     32     {
     33         Queue<Integer> q = new Queue<Integer>();
     34         color[s] = false;                                           // 颜色使用 true / false
     35         marked[s] = true;
     36         for (q.enqueue(s); !q.isEmpty();)
     37         {
     38             int v = q.dequeue();
     39             for (int w : G.adj(v))
     40                 if (!marked[w])
     41                 {
     42                     marked[w] = true;
     43                     edgeTo[w] = v;
     44                     color[w] = !color[v];
     45                     q.enqueue(w);
     46                 }
     47                 else if (color[w] == color[v])                      // w 已经遍历过,且形成了奇数长度的环
     48                 {
     49                     isBipartite = false;
     50                     cycle = new Queue<Integer>();
     51                     Stack<Integer> stack = new Stack<Integer>();
     52                     int x = v, y = w;                               // 两端同时向回走,color[v] == color[w] 于是 color[x] == color[y]
     53                     for (; x != y; x = edgeTo[x], y = edgeTo[y])    // 存在节点 z 使得 edgeTo[x] == edgeTo[y] == z,循环结束时 x 和 y 均指向公共顶点 z                          
     54                     {
     55                         stack.push(x);
     56                         cycle.enqueue(y);
     57                     }
     58                     for (stack.push(x); !stack.isEmpty(); cycle.enqueue(stack.pop()));  // 公共顶点 z 压栈,然后吐栈拼入队列,多一步是防止本来栈空
     59                     cycle.enqueue(w);
     60                     return;
     61                 }
     62         }
     63     }
     64 
     65     public boolean isBipartite()
     66     {
     67         return isBipartite;
     68     }
     69 
     70     public boolean color(int v)
     71     {
     72         if (!isBipartite)
     73             throw new UnsupportedOperationException("
    <color> Graph is not bipartite.
    ");
     74         return color[v];
     75     }
     76 
     77     public Iterable<Integer> oddCycle()
     78     {
     79         return cycle;
     80     }
     81 
     82     public static void main(String[] args)
     83     {
     84         int V1 = Integer.parseInt(args[0]);
     85         int V2 = Integer.parseInt(args[1]);
     86         int E = Integer.parseInt(args[2]);
     87         int F = Integer.parseInt(args[3]);
     88         Graph G = GraphGenerator.bipartite(V1, V2, E);
     89         for (int i = 0; i < F; i++)
     90         {
     91             int v = StdRandom.uniform(V1 + V2);
     92             int w = StdRandom.uniform(V1 + V2);
     93             G.addEdge(v, w);
     94         }
     95         StdOut.println(G);
     96 
     97         class01 b = new class01(G);
     98         if (b.isBipartite())
     99         {
    100             StdOut.println("Graph is bipartite");
    101             for (int v = 0; v < G.V(); v++)
    102                 StdOut.println(v + ": " + b.color(v));
    103         }
    104         else
    105         {
    106             StdOut.print("Graph has an odd-length cycle: ");
    107             for (int x : b.oddCycle())
    108                 StdOut.print(x + " ");
    109             StdOut.println();
    110         }
    111     }
    112 }
  • 相关阅读:
    更多的bash shell命令
    Docker(一)Docker概述
    SpringCloud(一)版本选择
    Scala 技术笔记之 可变长参数
    嵌入式 ThriftServer in Spark
    Spark 代码走读之 Cache
    Scala 技术笔记之 Option Some None
    Spark作业执行
    Shuffle
    Jetty初探
  • 原文地址:https://www.cnblogs.com/cuancuancuanhao/p/9824170.html
Copyright © 2020-2023  润新知