C ++程序使用二进制搜索查找图形的最小顶点覆盖大小

在本文中,我们将讨论一个使用二进制搜索来找到给定图的最小顶点覆盖大小的程序。

最小顶点覆盖度是给定图的一组顶点,以使图中的每个边均入射到该组顶点中的任何一个顶点。

例如,以图

2 ---- 4 ---- 6
|     |
|     |
|     |
3 ---- 5

此处,最小顶点覆盖涉及顶点3和4。所有图的边都入射到图的3或4个顶点上。

示例

#include<bits/stdc++.h>
using namespace std;
#define max 15
//数组来存储图形
bool arr[max][max];
//检查是否存在最小顶点覆盖
bool check_cover(int V, int k, int E) {
   int set = (1 << k) - 1;
   int limit = (1 << V);
   //标记大小为“ k”的边缘
   bool vis[max][max];
   while (set < limit) {
      //为每次迭代重置顶点覆盖
      memset(vis, 0, sizeof vis);
      int count = 0;
      //检查具有较高值的​​值
      for (int j = 1, v = 1 ; j < limit ; j = j << 1, v++) {
         if (set & j) {
            //标记访问过的边缘
            for (int k = 1 ; k <= V ; k++) {
               if (arr[v][k] && !vis[v][k]) {
                  vis[v][k] = 1;
                  vis[k][v] = 1;
                  count++;
               }
            }
         }
      }
      //如果所有边缘都被覆盖
      if (count == E)
         return true;
      int c = set & -set;
      int r = set + c;
      set = (((r^set) >> 2) / c) | r;
   }
   return false;
}
//找到最小顶点覆盖
int find_cover(int n, int m) {
   //执行二进制搜索
   int left = 1, right = n;
   while (right > left){
      int mid = (left + right) >> 1;
      if (check_cover(n, mid, m) == false)
         left = mid + 1;
      else
         right = mid;
   }
   return left;
}
//在图中插入边
void add_edge(int u, int v) {
   arr[u][v] = 1;
   arr[v][u] = 1;
}
int main() {
   memset(arr, 0, sizeof arr);
   int V = 6, E = 5;
   add_edge(2, 3);
   add_edge(2, 4);
   add_edge(3, 5);
   add_edge(4, 5);
   add_edge(4, 6);
   cout << "Size of Minimum Vertex Cover : " << find_cover(V, E) << endl;
   return 0;
}

输出结果

Size of Minimum Vertex Cover : 2