SPOJ:顶盖(PT07X)错误答案

时间:2015-01-21 12:47:05

标签: algorithm graph-algorithm

我正在尝试顶点覆盖问题。即使是一个不完美的代码也清除了所有关于soj判断的案例,但是我得到了一个测试用例(在评论中),它失败了,所以我试图删除它。但是,现在它不接受。 Problem Link

问题描述:你必须找到一个有意的无向树的顶点覆盖,即在这个树中找到一个最小尺寸的顶点集,这样每个边在该集合中至少有一个端点。

我的算法基于DFS。之前我使用了一个直截了当的逻辑,即DFS和回溯时,如果不包括子顶点,则包括其父级(如果尚未包含)。而且,它被接受了。但是,它在一个简单的具有6个顶点的倾斜树的情况下失败了。答案应该是2,但是它给了3.所以,我做了一些修改。

我添加了另一个参数来检查顶点是否已被其父级或其子级覆盖,如果是,则忽略。因此,每当找到一个尚未覆盖的顶点时,我会在顶点集中添加它的父节点。

我的旧源代码:

vector<int> edge[100000]; // to store edges
bool included[100000];    // to keep track of elements in vertex cover set
bool done[100000];        // to keep track of undiscivered nodes to do DFS on tree
int cnt;                  // count the elements in vertex set

/* Function performs DFS and makes a vertex cover set */
bool solve(int source){
  done[source] = true;
  for(unsigned int i = 0; i<edge[source].size(); ++i){
    if(!done[edge[source][i]]){  // if node is undiscovered
      if(!solve(edge[source][i]) && !included[source]){   // if child node is not included and neither its parent
         included[source] = true;    // element added to vertex cover set
         cnt++;                      // increasing the size of set
      }
    }
  }
  return included[source]; // return the status of current source vertex
}

int main(){
  int n,u,v;
  scanint(n);
  for(int i = 0; i<n-1; ++i){
    done[i] = false;
    included[i] = false;
    scanint(u);
    scanint(v);
    edge[u-1].push_back(v-1);
    edge[v-1].push_back(u-1);
  }
  done[n-1] = false;
  included[n-1] = false;
  cnt = 0;
  solve(0);
  printf("%d\n", cnt);
  return 0;
}

我的新源代码:

vector<int> edge[100000];   // to store edges
bool incld[100000];         // to keep track of nodes in vertex cover set
bool covrd[100000];         // to keep track of nodes already covered
bool done[100000];          // to keep track of undiscovered nodes to perform DFS
int cnt;                    // keep track of size of vertex cover set

/* Function to calculate vertex cover set via DFS */
void solve(int source){
  int child;   // to store index of child node
  done[source] = true;
  for(unsigned int i = 0; i<edge[source].size(); ++i){
    if(!done[edge[source][i]]){ // if child node is undiscovered
      child = edge[source][i];  
      if(incld[child])          // if child node is included in vertex set
         covrd[source] = true;  // setting current node to be covered
      else if(!covrd[child] && !incld[source]){ // if child node is not covered and current node is not included in vertex set
         incld[source] = true;     // including current node
         covrd[child] = true;      // covering child node
         cnt++;                    // incrementing size of vertex cover set
      }
    }
  }
}

int main(){
  int n,u,v;
  scanint(n);
  for(int i = 0; i<n-1; ++i){
    done[i] = false;
    incld[i] = false;
    covrd[i] = false;
    scanint(u);
    scanint(v);
    edge[u-1].push_back(v-1);
    edge[v-1].push_back(u-1);
  }
  done[n-1] = false;
  incld[n-1] = false;
  covrd[n-1] = false;
  cnt = 0;
  solve(0);
  printf("%d\n", cnt);
  return 0;
}

请帮忙。

1 个答案:

答案 0 :(得分:-1)

您的第一个解决方案是正确的(您可以找到证据here)。具有6个顶点的偏斜树的答案实际上是3(链接中的注释表示答案是2是错误的。)