Description
给出一个求最小点覆盖的贪心算法,代码如下,要求构造一张顶点数不超过 500 的无向图使得该算法求出的点覆盖数是其最小点覆盖数的三倍以上,要求输出点数边数和每条边以及最小点覆盖集的点的编号
for (int i = 1; i <= n; ++i) {
use[i] = false;
deg[i] = degree of the vertex i;
}
int ans = 0;
while (true) {
int mx = -1, u;
for (int i = 1; i <= n; ++i) {
if (use[i])
continue;
if (deg[i] >= mx) {
mx = deg[i];
u = i;
}
}
if (mx <= 0)
break;
++ans;
use[u] = true;
for (each vertex v adjacent to u)
--deg[v];
}
return ans;
Input
无输入
Output
输出点数边数和每条边以及最小点覆盖集的点的编号
Sample Input
无
Sample Output
无
Solution
该算法即每次选出度数最大的点中编号最大的,直观想法是构造一个二分图,左边点有
n
个,右边点
Code
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#include<queue>
#include<map>
#include<set>
#include<ctime>
using namespace std;
typedef long long ll;
typedef pair<int,int>P;
const int INF=0x3f3f3f3f,maxn=100001;
int main()
{
int n=15,m=0;
for(int i=1;i<=n;i++)m+=n/i*i;
printf("%d %d\n",4*n,m);
int res=n;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n/i;j++)
for(int k=1;k<=i;k++)
printf("%d %d\n",(j-1)*i+k,res+j);
res+=n/i;
}
printf("%d\n",n);
for(int i=1;i<=n;i++)printf("%d\n",i);
return 0;
}