Graph - Как найти максимальный индуцированный подграф H группы G такой, что каждая вершина в H имеет степень ≥ k

Вот акциз для графика.

Учитывая неориентированный граф G с n вершинами и m ребрами и целое число k, дадим алгоритм O (m + n), который найдет максимальный индуцированный подграф H группы G такой, что каждая вершина в H имеет степень ≥ k или доказать, что такой граф не существует. Индуцированный подграф F = (U, R) графа G = (V, E) является подмножеством U вершин V группы G и всех ребер R группы G таких, что обе вершины каждого ребра находятся в U.

Моя первоначальная идея такова:

Во-первых, этот акциз фактически просит, чтобы у нас были все вершины S, степени которых больше или равны k, тогда мы удаляем вершины в S, у которых нет ребра, связанного с другими. Тогда уточненный S есть H, в котором все вершины имеют степень >= k, а ребра между ними R.

Кроме того, он запрашивает O (m + n), поэтому мне кажется, что мне нужно BFS или DFS. Затем я застреваю.

В BFS я могу знать степень вершины. Но как только я получаю степень v (вершина), я не знаю других связанных вершин, кроме своего родителя. Но если родитель не имеет степени >= k, я не могу устранить v, поскольку он все еще может быть связан с другими.

Любые подсказки?


Изменить:

В соответствии с ответом @Michael J. Barber, я внедрил его и обновил код здесь:

Может ли кто-нибудь взглянуть на ключевой метод кодов public Graph kCore(Graph g, int k)? Правильно ли я это делаю? Это O (m + n)?

class EdgeNode {
   EdgeNode next;
   int y;
}

public class Graph {
   public EdgeNode[] edges;
   public int numVertices;

   public boolean directed;

   public Graph(int _numVertices, boolean _directed) {
      numVertices = _numVertices;
      directed = _directed;
      edges = new EdgeNode[numVertices];
   }

   public void insertEdge(int x, int y) {
      insertEdge(x, y, directed);
   }

   public void insertEdge(int x, int y, boolean _directed) {
      EdgeNode edge = new EdgeNode();
      edge.y = y;
      edge.next = edges[x];
      edges[x] = edge;
      if (!_directed)
          insertEdge(y, x, true);
   }

   public Graph kCore(Graph g, int k) {
      int[] degree = new int[g.numVertices];
      boolean[] deleted = new boolean[g.numVertices];
      int numDeleted = 0;
      updateAllDegree(g, degree);// get all degree info for every vertex

      for (int i = 0;i < g.numVertices;i++) {
          **if (!deleted[i] && degree[i] < k) {
           deleteVertex(p.y, deleted, g);
          }**
      }

      //Construct the kCore subgraph
      Graph h = new Graph(g.numVertices - numDeleted, false);
      for (int i = 0;i < g.numVertices;i++) {
         if (!deleted[i]) {
           EdgeNode p = g[i];
           while(p!=null) {
              if (!deleted[p.y])
                 h.insertEdge(i, p.y, true); // I just insert the good edge as directed, because i->p.y is inserted and later p.y->i will be inserted too in this loop.
                 p = p.next;
              }
           }
         }
      }

      return h;
  }

  **private void deleteVertex(int i, boolean[] deleted, Graph g) {
     deleted[i] = true;
     EdgeNode p = g[i];
     while(p!=null) {
        if (!deleted[p.y] && degree[p.y] < k) 
            deleteVertex(p.y, deleted, g);
        p = p.next;
     }
  }**

  private void updateAllDegree(Graph g, int[] degree) {
     for(int i = 0;i < g.numVertices;i++) {
         EdgeNode p = g[i];
         while(p!=null) {
            degree[i] += 1;
            p = p.next;
         }
     }
  }

}

Ответ 1

Максимальный индуцированный подграф, где вершины имеют минимальную степень k, называется k-core. Вы можете найти k-сердечники, просто удалив любые вершины со степенью меньше k.

На практике вы сначала оцениваете степень всех вершин, которая равна O (m). Затем вы проходите через вершины, ища вершины со степенью меньше k. Когда вы найдете такую ​​вершину, вырежьте ее из графика и обновите степени соседей, а также удалите все соседи, чьи градусы опускаются ниже k. Вам нужно посмотреть каждую вершину хотя бы один раз (так можно сделать в O (n)) и обновить степени не более одного раза для каждого ребра (что делает возможным в O (m)), что дает полную асимптотическую оценку O (m + n),

Остальные компоненты связности являются k-ядрами. Найдите самую большую, оценив их размеры.