查看: 1840| 回复: 5
跳转到指定楼层
上一主题 下一主题
收起左侧

[学C/C++] 小白求助BFS, 计算距离

全局:

注册一亩三分地论坛,查看更多干货!

您需要 登录 才可以下载或查看附件。没有帐号?注册账号

x
要求只能更改红字部分, 不能用visited
红字部分是我的想法, 但是结果不对
应该怎么修改才能得到正确答案?
非常感谢!


  1. #include <iostream>
  2. #include <string>

  3. // Note: You must not change the definition of DisjointSets here.
  4. class DisjointSets {
  5. public:
  6.   int s[256];
  7.   int distance[256];

  8.   DisjointSets() {
  9.     for (int i = 0; i < 256; i++) s[i] = distance[i] = -1;
  10.   }

  11.   int find(int i) { return s[i] < 0 ? i : find(s[i]); }
  12.   
  13.   void dsunion(int i, int j) {
  14.     int root_i = find(i);
  15.     int root_j = find(j);
  16.     if (root_i != root_j) {
  17.       s[root_i] = root_j;
  18.     }
  19.   }
  20.   
  21.   void bfs(int i, int n, int m, int edges[][2]);
  22. };


  23. /* Below are two conditions that need to be programmed
  24. * to allow this procedure to perform a breadth first
  25. * traversal and mark the edge distance of the graph's
  26. * vertices from vertex i.
  27. */

  28. void DisjointSets::bfs(int i, int n, int m, int edges[][2]) {
  29.   
  30.   distance[i] = 0;

  31.   // no need to iterate more than m times
  32.   // but loop terminates when no new
  33.   // vertices added to the frontier.
  34.   
  35.   for (int d = 1; d < m; d++) {
  36.    
  37.     // f is the index of the first
  38.     // vertex added to the frontier
  39.     int f = -1;

  40.     // rooti is the name of the set
  41.     // holding all of the vertices
  42.     // that have already been assigned
  43.     // distances
  44.    
  45.     int rooti = find(i);

  46.     // loop through all of the edges
  47.     // (this could be much more efficient
  48.     // if an adjacency list was used
  49.     // instead of a simple edge list)
  50.    
  51.     for (int j = 0; j < m; j++) {

  52.       // root0 and root1 are the names of
  53.       // the sets that the edge's two
  54.       // vertices belong to

  55.       int root0 = find(edges[j][0]);
  56.       int root1 = find(edges[j][1]);
  57.       

  58.       if ( [color=#ff0000]root1 != rooti[/color] ) {

  59.         // add the [1] vertex of the edge
  60.         // to the frontier, either by
  61.         // setting f to that vertex if it
  62.         // is the first frontier vertex
  63.         // found so far, or by unioning
  64.         // it with the f vertex that was
  65.         // already found.
  66.         
  67.         if (f == -1)
  68.           f = edges[j][1];
  69.         else
  70.           dsunion(f,edges[j][1]);

  71.         // set the distance of this frontier
  72.         // vertex to d

  73.         distance[edges[j][1]] = d;
  74.         
  75.       } else if ( [color=#ff0000]root0 != rooti[/color] ) {
  76.         if (f == -1)
  77.           f = edges[j][0];
  78.         else
  79.           dsunion(f,edges[j][0]);
  80.         distance[edges[j][0]] = d;
  81.       }
  82.     }
  83.    
  84.     // if no vertices added to the frontier
  85.     // then we have run out of vertices and
  86.     // are done, otherwise union the frontier
  87.     // set with the set of vertices that have
  88.     // already been processed.
  89.    
  90.     if (f == -1)
  91.       break;
  92.     else
  93.       dsunion(f,i);
  94.   }
  95. }

  96. int main() {

  97.   int edges[8][2] = {{0,1},{1,2},{2,3},{3,4},{4,5},{5,6},{6,7},{7,3}};  

  98.   DisjointSets d;

  99.   d.bfs(3,8,8,edges);

  100.   for (int i = 0; i < 8; i++)
  101.     std::cout << "Distance to vertex " << i
  102.               << " is " << d.distance[i] << std::endl;

  103. // Should print
  104. // Distance to vertex 0 is 3
  105. // Distance to vertex 1 is 2
  106. // Distance to vertex 2 is 1
  107. // Distance to vertex 3 is 0
  108. // Distance to vertex 4 is 1
  109. // Distance to vertex 5 is 2
  110. // Distance to vertex 6 is 2
  111. // Distance to vertex 7 is 1


  112.   return 0;
  113. }
复制代码


[/i][/i][/i][/i][/i][/i]

上一篇:32岁转行CS - 其实就是零基础
下一篇:关于转行CS 的几点建议,
全局:
本帖最后由 不知道小帅 于 2020-5-30 12:00 编辑

没看到有红字部分啊。而且不是很清楚你的m和n的定义,这感觉就是在并查集里面运行bfs.如果我理解是对的话,就是需要填if和else if的判断条件。
第一个if的地方填 root0 == rooti && root1 != rooti, 第二个 else if那里填root1 == rooti && root0 != rooti

评分

参与人数 1大米 +1 收起 理由
ifiaxxy + 1 非常感谢!

查看全部评分

回复

使用道具 举报

全局:
思考过程是这样的,root0 == rooti的话,说明这条边的edge[0]已经被访问过了,那么另一个点到你的source的距离自然就是+1了。你对d进行循环,就实现了这个功能。
逻辑就是所有访问过的点,都会union起来,root都会变成你的起点i。所以只要看一下root是不是你的起点,就知道当前节点有没有被访问过了。

评分

参与人数 1大米 +1 收起 理由
ifiaxxy + 1 非常感谢!

查看全部评分

回复

使用道具 举报

🔗
tinlittle 2020-5-30 12:35:54 | 只看该作者
全局:
Python写这个就20行代码。你这100多行,建议刷题还是早转Python吧,磨刀不误砍柴工。
回复

使用道具 举报

全局:
tinlittle 发表于 2020-5-30 12:35
Python写这个就20行代码。你这100多行,建议刷题还是早转Python吧,磨刀不误砍柴工。

也没那么大差距啊,除掉注释也就是三四十行。写一个并查集本身确实就需要一些代码量了。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册账号
隐私提醒:
  • ☑ 禁止发布广告,拉群,贴个人联系方式:找人请去🔗同学同事飞友,拉群请去🔗拉群结伴,广告请去🔗跳蚤市场,和 🔗租房广告|找室友
  • ☑ 论坛内容在发帖 30 分钟内可以编辑,过后则不能删帖。为防止被骚扰甚至人肉,不要公开留微信等联系方式,如有需求请以论坛私信方式发送。
  • ☑ 干货版块可免费使用 🔗超级匿名:面经(美国面经、中国面经、数科面经、PM面经),抖包袱(美国、中国)和录取汇报、定位选校版
  • ☑ 查阅全站 🔗各种匿名方法

本版积分规则

>
快速回复 返回顶部 返回列表