错误答案 ACM A 节点太远

发布于 2024-12-29 19:30:03 字数 5066 浏览 0 评论 0原文

我已经为问题“节点太远”问题 id uva 336 编写了代码。但是它给出了错误的答案,任何人都可以猜出我做错了什么。下面是我的代码。

问题的链接是 A Node too far

另外,如果有人可以告诉我什么是得到错误答案的常见原因,我们有什么方法可以知道我们的程序针对哪些输入产生了问题。

#include <iostream>
#include <vector>
#include <list>
#include <map>

unsigned int caseID = 0;
struct Edge;

struct Node{
   Node():id(0),cost(0),color(false),added(false){}
   int id;
   int cost;
   bool color;
   bool added;
   std::list<Edge *>edges;
};
struct Edge{
 Edge():destination(0){}

 Node *destination;
};


void make_graph(unsigned int sourceid,unsigned int destinationid,
    std::map<int, Node*> &mymap, int &totalNodes){
    Node *source = 0;
    Node *destination = 0;

    std::map<int, Node*>::iterator it = mymap.find(sourceid);
    if(it == mymap.end()){
     source = new Node;
     ++ totalNodes;
     source->id = sourceid;
     mymap.insert(std::pair<int,Node*> (sourceid,source));
   }
   else{
     source = it->second;
   }
   if(sourceid == destinationid){
     return;
   }

   it = mymap.find(destinationid);
   if(it == mymap.end()){
      ++totalNodes;
      destination = new Node;
      destination->id= destinationid;
      mymap.insert(std::pair<int,Node*> (destinationid,destination));

   }
   else{
      destination = it->second;
   }

   Edge *e = new Edge;
   e->destination = destination;
   source->edges.push_back(e);

   e = new Edge;
   e->destination = source;
   destination->edges.push_back(e);

 }



  void delete_graph(std::map<int, Node*> &mymap){
     std::map<int,Node*>::iterator it = mymap.begin();
     for(;it != mymap.end(); ){

       Node *n = it->second;
       if(!n){
         continue;
       }
       std::list<Edge *>::iterator myEdge = it->second->edges.begin();

          while(myEdge != n->edges.end()){
          Edge *e = *myEdge;
          if(e){
          e->destination = 0;
          delete e;
          e = 0;
          }
          ++myEdge;
       }
       delete n;
       n = 0;
       ++it;
       std::cout << std::endl;
      }
    }


      void calc_nodes(int value, Node *n, unsigned int &nodesCount, int prevCost){

        if(!n->added){
          n->cost = ++prevCost;
          if(n->cost == value){
           ++nodesCount;
           n->added = true;
           return;
         }
          ++nodesCount;
          n->added = true;

         }else{
           n->cost =  ++prevCost;
          }

        std::list<Edge *>::iterator it = n->edges.begin();
        while(it != n->edges.end()){
            Edge *e = *(it);
             if(e->destination->color){
                ++it;
                continue;
             }

           n->color = true;
           e->destination->color = true;
           calc_nodes(value,e->destination,nodesCount,n->cost);
           ++it;
        }

     }

     void clearGraph(std::map<int, Node *>& mymap ){
            std::map<int, Node *>::iterator it = mymap.begin();
            while(it != mymap.end()){
               it->second->added = false;
               it->second->color = false;
               ++it;
            }
    }

     void calc_nodes_aux(int totalNodes,std::map<int,Node *> &mymap){
         unsigned int TTL = 0;
         Node *source = 0;
         unsigned int sourceId = 0;
          unsigned int nodesCount = 0;
         while(true){
           std::cin >> sourceId >>TTL;
              if(sourceId == 0 && TTL == 0){
                   break;
              }    
          std::map<int,Node *>::iterator it = mymap.find(sourceId);
          source = it->second;

          if(source && TTL > 0){
             nodesCount = 0;
             clearGraph(mymap);
             calc_nodes(TTL,source,nodesCount, -1);
             if(caseID > 0){
                    std::cout <<std::endl;
             }
            std::cout << "Case "<< ++caseID<<": " <<totalNodes - nodesCount <<
       " nodes not reachable from node " <<sourceId << " with TTL = " << TTL<<".";
            }
           }
          }
       int main(){

            unsigned int edges = 0;
            unsigned int sourceId = 0;
             unsigned int destinationId = 0;
             while(true){
               std::cin >>edges;
                if(edges == 0){
                  break;
                } 
               std::map<int,Node*>mymap;
                int totalNodes = 0;
               for(unsigned int i = 0; i < edges; ++i ){
                    std::cin >> sourceId >> destinationId;
                    make_graph(sourceId,destinationId,mymap,totalNodes);
               }
              calc_nodes_aux(totalNodes,mymap);
              delete_graph(mymap);
          }
          return 0;
      } 

I have written code for the problem "A Node too far" problem id uva 336. But it is giving wrong answer can any one guess what i am doing wrong. Below is my code.

The link to the problem is A Node too far

Also if someone can tell me what is the common reasons for getting a wrong answer and is there any way that we know that against which input our program is creating problems.

#include <iostream>
#include <vector>
#include <list>
#include <map>

unsigned int caseID = 0;
struct Edge;

struct Node{
   Node():id(0),cost(0),color(false),added(false){}
   int id;
   int cost;
   bool color;
   bool added;
   std::list<Edge *>edges;
};
struct Edge{
 Edge():destination(0){}

 Node *destination;
};


void make_graph(unsigned int sourceid,unsigned int destinationid,
    std::map<int, Node*> &mymap, int &totalNodes){
    Node *source = 0;
    Node *destination = 0;

    std::map<int, Node*>::iterator it = mymap.find(sourceid);
    if(it == mymap.end()){
     source = new Node;
     ++ totalNodes;
     source->id = sourceid;
     mymap.insert(std::pair<int,Node*> (sourceid,source));
   }
   else{
     source = it->second;
   }
   if(sourceid == destinationid){
     return;
   }

   it = mymap.find(destinationid);
   if(it == mymap.end()){
      ++totalNodes;
      destination = new Node;
      destination->id= destinationid;
      mymap.insert(std::pair<int,Node*> (destinationid,destination));

   }
   else{
      destination = it->second;
   }

   Edge *e = new Edge;
   e->destination = destination;
   source->edges.push_back(e);

   e = new Edge;
   e->destination = source;
   destination->edges.push_back(e);

 }



  void delete_graph(std::map<int, Node*> &mymap){
     std::map<int,Node*>::iterator it = mymap.begin();
     for(;it != mymap.end(); ){

       Node *n = it->second;
       if(!n){
         continue;
       }
       std::list<Edge *>::iterator myEdge = it->second->edges.begin();

          while(myEdge != n->edges.end()){
          Edge *e = *myEdge;
          if(e){
          e->destination = 0;
          delete e;
          e = 0;
          }
          ++myEdge;
       }
       delete n;
       n = 0;
       ++it;
       std::cout << std::endl;
      }
    }


      void calc_nodes(int value, Node *n, unsigned int &nodesCount, int prevCost){

        if(!n->added){
          n->cost = ++prevCost;
          if(n->cost == value){
           ++nodesCount;
           n->added = true;
           return;
         }
          ++nodesCount;
          n->added = true;

         }else{
           n->cost =  ++prevCost;
          }

        std::list<Edge *>::iterator it = n->edges.begin();
        while(it != n->edges.end()){
            Edge *e = *(it);
             if(e->destination->color){
                ++it;
                continue;
             }

           n->color = true;
           e->destination->color = true;
           calc_nodes(value,e->destination,nodesCount,n->cost);
           ++it;
        }

     }

     void clearGraph(std::map<int, Node *>& mymap ){
            std::map<int, Node *>::iterator it = mymap.begin();
            while(it != mymap.end()){
               it->second->added = false;
               it->second->color = false;
               ++it;
            }
    }

     void calc_nodes_aux(int totalNodes,std::map<int,Node *> &mymap){
         unsigned int TTL = 0;
         Node *source = 0;
         unsigned int sourceId = 0;
          unsigned int nodesCount = 0;
         while(true){
           std::cin >> sourceId >>TTL;
              if(sourceId == 0 && TTL == 0){
                   break;
              }    
          std::map<int,Node *>::iterator it = mymap.find(sourceId);
          source = it->second;

          if(source && TTL > 0){
             nodesCount = 0;
             clearGraph(mymap);
             calc_nodes(TTL,source,nodesCount, -1);
             if(caseID > 0){
                    std::cout <<std::endl;
             }
            std::cout << "Case "<< ++caseID<<": " <<totalNodes - nodesCount <<
       " nodes not reachable from node " <<sourceId << " with TTL = " << TTL<<".";
            }
           }
          }
       int main(){

            unsigned int edges = 0;
            unsigned int sourceId = 0;
             unsigned int destinationId = 0;
             while(true){
               std::cin >>edges;
                if(edges == 0){
                  break;
                } 
               std::map<int,Node*>mymap;
                int totalNodes = 0;
               for(unsigned int i = 0; i < edges; ++i ){
                    std::cin >> sourceId >> destinationId;
                    make_graph(sourceId,destinationId,mymap,totalNodes);
               }
              calc_nodes_aux(totalNodes,mymap);
              delete_graph(mymap);
          }
          return 0;
      } 

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

摘星┃星的人 2025-01-05 19:30:03

对于给定的任务,您的代码非常复杂,您甚至没有通过示例测试!请注意,在(几乎所有)在线法官中,您需要生成与预期字节相同的输出。在第一个测试用例之后,您输出大约 10 个额外的换行符,即使您的代码在其他方面是正确的,这也会导致错误的答案。

以下是如何轻松解决此特定问题的两种方法:

您所需要做的就是构建节点图,然后运行 ​​从查询中的节点开始广度优先搜索。之后,计算与初始节点的最短距离大于给定阈值(TTL)的所有节点。

由于节点数量非常小(最多 30 个),替代解决方案是运行 Floyd Warshall 算法。该解决方案会更短,但不适用于更大的约束。

这两种方法都可以轻松地用不到 50 行来容纳。

如何找到您有 WA 的测试的一种方法是尝试生成随机图并模拟包裹在任意两个节点之间的移动,并将结果与​​程序找到的结果进行比较。总是生成小例子!在这种情况下,我相信最多 5 个节点就足够了。

第二种方法,我通常更喜欢的是手动生成图表并再次手动计算预期答案。尝试覆盖尽可能多的边缘情况(网络中的单个节点、所有节点均可到达、TTL 为 0 等)。
在在线评委中,只有少数人提供选项来查看您的代码在哪种情况下失败,而 UVA 不是其中之一。这样做是有目的的 - 它迫使您自己尝试和调试程序。同样在 ACM 决赛中,没有人会告诉你你失败的情况。

Your code is extremely complicated for the task given and you do not even pass the example test! Please note that in (almost all) online judges you are required to produce an output that is the same byte-wise as the expected one. You output about 10 additional newline characters after the first test case and even if your code is otherwise correct this will result in wrong answer.

Here are two approaches on how to solve this particular problem with less effort:

All you need to do is to build the graph of nodes and then run a breadth first search from the node in the query. After that count all nodes that have their shortest distance to the initial node greater then the given threshold(the TTL).

As the number of nodes is really small(up to 30), an alternative solution would be to run a Floyd Warshall algorithm. This solution will be even shorter but will not work for much greater constraints.

Both approaches could easily fit in less then 50 lines.

One approach on how to find which test do you have WA is to try generating random graphs and simulate the movement of the packages between any two nodes and compare the result with the one found by your program. Always generate small examples! In this case I believe up to 5 nodes is more then enough.

Second approach, which I generally prefer is to generate graphs by hand and compute the expected answer again by hand. Try to cover as many edge cases as possible(single node in the network, all nodes are reachable, TTL is 0 and so on).
In the online judges only a few offer the option to see which case is your code failing on and UVA is not one of them. This is done for a purpose - it forces you to try and debug your program on your own. Also on ACM finals no one is going to tell you the case that you are failing.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文