【HDU - 6150 】Vertex Cover(構造)

As we know, minimumvertexcoverminimumvertexcover is a classical NP-complete problem. There will not be polynomial time algorithm for it unless P=NPP=NP. 

You can see the definition of vertex cover in https://en.wikipedia.org/wiki/Vertex_cover. 

Today, little M designs an "approximate" algorithm for vertex cover. It is a greedy algorithm. The main idea of her algorithm is that always choosing the maximum degree vertex into the solution set. The pseudo code of her algorithm is as follows: 

We assume that the labels of the vertices are from 1 to n. 

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;



As a theory computer scientist, you immediately find that it is a bad algorithm. To show her that this algorithm dose not have a constant approximate factor, you need to construct an instance of vertex cover such that the solution get by this algorithm is much worse than the optimal solution. 

Formally, your program need to output a simple undirected graph of at most 500500vertices. Moreover, you need to output a vertex cover solution of your graph. Your program will get Accept if and only if the solution size get by the above algorithm is at least three times as much as yours. 

Input

There is no input. 

Output

First, output two integer nn and mm in a line, separated by a space, means the number of the vertices and the number of the edges in your graph. 
In the next mm lines, you should output two integers uu and vv for each line, separated by a space, which denotes an edge of your graph. It must be satisfied that 1≤u,v≤n1≤u,v≤n and your graph is a simple undirected graph. 
In the next line, output an integer k(1≤k≤n)k(1≤k≤n), means the size of your vertex cover solution. 
Then output kk lines, each line contains an integer u(1≤u≤n)u(1≤u≤n) which denotes the label of a vertex in your solution. It must be satisfied that your solution is a vertex cover of your graph. 

Sample Output

4 4
1 2
2 3
3 4
4 1
2
1
3


        
  

Hint

The sample output is just to exemplify the output format.

        

題意:

自己構造一個圖,使得他給的程序跑出的最小點覆蓋,是自己輸出的最小點覆蓋的點數的3倍。

思路:(參考博客

讀程序,要注意,他的程序是優先度數最大的點,即連邊數量最多的,如果相同的就選編號較大的。

因此可以這樣構造,一開始有n個點,這些點是最小點覆蓋,然後循環n次,每次添加n/i個新的點,讓新添加的點和之前的i個點連邊(開始的n個點這一輪每個點只能用一次),這樣能保證最開始的n個點的度數每次增加1,第i輪度數最大的爲i,而且新添加的點的度數也都是i。因此可以先選新添加的點,最後再選最開始的n個點。這樣用它程序跑出的點數是\sum _{i=1}^{n}\left \lfloor \frac{n}{i} \right \rfloor,我們輸出的點數是n。通過循環加一下可以發現當n=25時就可以滿足條件了。

 

ac代碼:

#include<cstdio>
#include<queue>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
vector<pair<int,int>> vv;
int main(){
	int n=25,sum=0,j,now=25;
	for(int i=1;i<=n;i++){
		for(j=0;j<n/i;j++){
			++now;
			for(int k=1;k<=i;k++)
			vv.push_back(make_pair(i*j+k,now));
		}
			
	}
	printf("%d %d\n",now,vv.size()); 
	for(auto v:vv) printf("%d %d\n",v.first,v.second);
	printf("%d\n",n);
	for(int i=1;i<=n;i++) printf("%d\n",i);
	return 0;
} 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章