hdu6150 构造题_ccpc

Vertex Cover

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 256000/256000 K (Java/Others)
Total Submission(s): 524    Accepted Submission(s): 207
Special Judge


Problem Description
As we know,  minimumvertexcover is a classical NP-complete problem. There will not be polynomial time algorithm for it unless  P=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  500 vertices. 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  n and  m 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  m lines, you should output two integers  u and  v for each line, separated by a space, which denotes an edge of your graph. It must be satisfied that  1u,vn and your graph is a simple undirected graph.
In the next line, output an integer  k(1kn), means the size of your vertex cover solution.
Then output  k lines, each line contains an integer  u(1un) 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.
 

Source
2017中国大学生程序设计竞赛 - 网络选拔赛


瞎构造题。。主要就是构造一个二分图 让左边的点是右边的点的三分之一,并且右边点的度数大于左边因为给的程序是每次贪心删去度数大的点。根据一遍论文中的内容, hdu6150 构造题_ccpc_第1张图片
大概就是构造这么个图形,把左边的点分块(从一块分到n块)然后连接右边的点就行了。
#include  
using namespace std;  
const int maxn = 1000010;
pair edge[maxn];  
int main(){  
    int l = 100, r = 100, tot = 0;  
    for (int i = 2; i <= l; i++){  
        for (int j = 0; j < l / i; j++){  //把左边分块 每次分块的大小是 l/i然后连接左右两边 即创建一个二分图 左边的点是n个 右边nlgn个 
            r++;  //右边新增的每一个点需要连接i个块 如果i==100那么就要连100个点 
            for (int k = 1; k <= i; k++) edge[++tot] = make_pair(r, i * j + k);  
        }  
    }  
    printf("%d %d\n",r,tot);  
    for(int i=1;i<=tot;i++)printf("%d %d\n",edge[i].first,edge[i].second);  
    printf("%d\n",l);  
    for(int i=1;i<=l;i++)printf("%d\n",i);  
    return 0;  
}  


 

你可能感兴趣的:(ACM_learning)