hdu 6150

2 篇文章 0 订阅

Vertex Cover

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 256000/256000 K (Java/Others)
Total Submission(s): 448    Accepted Submission(s): 173
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
 

Recommend
liuyiding  &nbsp|  &nbspWe have carefully selected several similar problems for you:   6160  6159  6158  6157  6156 
 

Statistic |  Submit |  Discuss | Note

题目给了个求无向图最小点覆盖的方法,直接贪心的每次都选出一个度最大的点,然后覆盖掉这个点周围的边。要输出一个图,贪心算法选的点要比正解多了三倍。这明显是一个错误的方法。因为这种贪心解决不了当有两个度数一样的点,先选哪个好的问题。然后比赛的时候只是一直想着构造多几个度数相同的点让他选错,没弄出其中的奇妙啊。
这里写图片描述
博客地址

这种想法是分成左右两组,左边的点是正解,右边的点那个贪心算法会选错的。
方法
如图,绿色的点是左边的点,黑色的点是右边的点,线段表示黑色的点跟谁连绿色的点连结上了。按照这种方法来连,那么黑色17是度最大的,会被先选上,然后绿色1~10都会度减一,此时16又变成最大了的,这样重复下去,终究是右边的全都被选上了啊。点数多一些的话,右边的点就会是左边的三倍。

#include<bits/stdc++.h>
using namespace std;

vector<pair<int,int>> e;
int main()
{
    if (fopen("in.txt", "r") != NULL)
    {
        freopen("in.txt", "r", stdin);
        freopen("out.txt", "w", stdout);
    }
    int l=100,r=100;
    for(int i=2;i<=l;i++)
    {
        for(int j=1;j*i<=l;j++)
        {
            r++;
            for(int k=i*(j-1)+1;k<=i*j;k++)
                e.push_back({r,k});
        }
    }
    cout<<r<<" "<<e.size()<<endl;
    for(auto ei : e)
        cout<<ei.first<<" "<<ei.second<<endl;
    cout<<l<<endl;
    for(int i=1;i<=l;i++)
        cout<<i<<endl;
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值