题目地址

hdu5438

题干

代码和解释

解答本题时参考了一篇代码较短的博客,比较有意思,使用了STL vector二维数组。

可以结合下面的示例代码理解:

  1. #include<iostream>
  2. #include<vector>
  3. using namespace std;
  4. int main()
  5. {
  6. vector<int> n[100];
  7. int i;
  8. for(i=0;i<100;i++){
  9. n[i].clear();
  10. }
  11. n[5].push_back(1);
  12. n[5].push_back(3);
  13. printf("%d\n",n[5].size());//为2
  14. printf("%d\n",n[5][0]);//为1
  15. printf("%d\n",n[5][1]);//为3
  16. //printf("%d\n",n[5]);//编译不通过
  17. return 0;
  18. }

可以理解为100行一维数组,每行长度不定,vector相当于变长数组。所以之前一维数组时对 n (vector<int> n)的操作在这里都对 n[i] (vector<int> n[100];int i;)应用。

本题的dfs跟网上的dfs基本模板差别有点大,不太易于作为dfs学习的开始,这里不详细解释。

这里是c++代码。

  1. #include<iostream>
  2. #include<vector>
  3. #include<cstring>
  4. #include<cstdio>
  5. using namespace std;
  6. int v[10010],f[10010],l[10010];//v存储每个池塘的值,f存储其是否被遍历过,l存储每个池塘连接管子数
  7. vector<int> x[10010];//x存储每个池塘与哪个池塘相连的具体情况
  8. int tmp;//tmp是已经遍历的节点个数
  9. long long sum1,sum2;
  10. void dfs(int t);
  11. int main()
  12. {
  13. int T,p,m,a,b;//T为样例组数,p为池塘数,m为连接组合数,a、b为每组连接中两个池塘的位置(编号)
  14. int i,j;
  15. int flag;
  16. scanf("%d",&T);
  17. while(T--){
  18. scanf("%d%d",&p,&m);
  19. sum1=0;
  20. memset(v,0,sizeof(v));
  21. memset(f,0,sizeof(f));
  22. memset(l,0,sizeof(l));//初始化
  23. for(i=0;i<10010;i++){
  24. x[i].clear();//初始化
  25. }
  26. for(i=1;i<=p;i++){//从1开始到p结束,不然会错,因为a和b存储位置是从1开始的
  27. scanf("%d",&v[i]);
  28. }
  29. for(i=0;i<m;i++){
  30. scanf("%d%d",&a,&b);
  31. x[a].push_back(b);//a与b相连
  32. x[b].push_back(a);//b与a相连
  33. l[a]++;//与a相连的池塘(管子)数加1
  34. l[b]++;//与b相连的池塘(管子)数加1
  35. }
  36. flag=1;
  37. while(flag==1){
  38. flag=0;//如果所有剩下的池塘连接管子数都大于等于2,则flag就会保持为0
  39. for(i=1;i<=p;i++){//i从1开始到p
  40. if(l[i]==0||l[i]==1){
  41. //连接管子数小于2
  42. flag=1;//只要这样的池塘还存在,就让flag为1,重新执行循环
  43. f[i]=1;//表示已经遍历过
  44. for(j=0;j<x[i].size();j++){//x[i].size表示位置为i的这个池塘连接的管子数
  45. l[x[i][j]]--;//让所有与位置为i的池塘相连的池塘的连接管子数减1,即删除了位置为i的池塘与其他池塘的连接关系
  46. }
  47. l[i]=-1;//表示连接管子数小于2
  48. }
  49. }
  50. }
  51. //这样处理完后就只剩下连接管子数大于等于2的池塘,接下来用dfs判断每个连接组合是否包含奇数个池塘
  52. for(i=1;i<=p;i++){//i从1开始到p
  53. if(f[i]==0){
  54. //说明是还没有遍历过的
  55. sum2=0;
  56. tmp=0;
  57. dfs(i);//经过这个操作,tmp变成这个组合中池塘的数量,sum2变成这个组合中所有池塘值的和,并且这个组合中所有池塘都被遍历过了
  58. if(tmp%2==1){//如果包含奇数个池塘
  59. sum1+=sum2;
  60. }
  61. }
  62. }
  63. printf("%lld\n",sum1);
  64. }
  65. return 0;
  66. }
  67. void dfs(int t){
  68. int i;
  69. tmp++;
  70. f[t]=1;//表示已经遍历过,这样就不会对同一个组合中的每个池塘多次计算了
  71. sum2+=v[t];//加上这个池塘的值
  72. for(i=0;i<x[t].size();i++){
  73. if(f[x[t][i]]==0){//对于与这个池塘相连的所有未被遍历过的池塘
  74. dfs(x[t][i]);
  75. }
  76. }
  77. return;
  78. }

解本题时一开始又读错了题意,最终要求加起来的是组合中池塘个数为奇数的,而我理解成了组合中的含值为奇数的池塘的。

参考

HDU 5438.Ponds【2015 ACM/ICPC Asia Regional Changchun Online】【DFS】9月13

hdu5438 Ponds[DFS,STL vector二维数组]的更多相关文章

  1. C++ vector二维数组

    C++ 构建二维动态数组 int **p; p = ]; //注意,int*[10]表示一个有10个元素的指针数组 ; i < ; ++i) { p[i] = ]; } 这样就构成10*5的数组 ...

  2. SDUT OJ 图练习-BFS-从起点到目标点的最短步数 (vector二维数组模拟邻接表+bfs , *【模板】 )

    图练习-BFS-从起点到目标点的最短步数 Time Limit: 1000ms   Memory limit: 65536K  有疑问?点这里^_^ 题目描述 在古老的魔兽传说中,有两个军团,一个叫天 ...

  3. c++ vector二维数组常见写法

    vector<vector <int> > array(3);//定义了行数为3列数不定的二维数组 array.size()//返回二维数组的行数 array[0].size( ...

  4. c++ vector & 二维数组 & MessageBox

    vector: https://www.cnblogs.com/mr-wid/archive/2013/01/22/2871105.html c++ 二维数组: int **p; p = new in ...

  5. Vector 二维数组 实现

    1.C++实现动态二维数组 int **p; p = ]; //注意,int*[10]表示一个有10个元素的指针数组 ; i < ; ++i) { p[i] = ]; } 2.利用指针数组实现二 ...

  6. c++用vector创建二维数组

    1 vector二维数组的创建和初始化 std::vector <int> vec(10,90); //将10个一维动态数组初始为90std::vector<std::vector& ...

  7. 转:用STL中的vector动态开辟二维数组

    用STL中的vector动态开辟二维数组 源代码:#include <iostream>#include <vector>using namespace std;int mai ...

  8. stl vector创建二维数组

    vector<vector<); for (auto it = v.begin(); it != v.end(); it++) { ; (*it).reserve();//预留空间为5,但 ...

  9. C++ vector 实现二维数组

    在STL中Vector这一容器,无论是在封装程度还是内存管理等方面都由于传统C++中的数组.本文主要是关于使用Vector初始化.遍历方面的内容.其他二维的思想也是类似的. 这里简单叙述一下C++ 构 ...

随机推荐

  1. Python的bytes和str

    Python和C的字符串 在Python 3 中,bytes单独作为一个类型,不再和str类型混在一起.关于字符串和字节,我想先回顾下C/C++ 在C/C++中,字符串是由char数组构成,每个元素是 ...

  2. Java 缓存实例

    重复创建相同的对象没有太大的意义,反而加大了系统开销,某些情况下,可以缓存该类的实例,实现复用. 实现缓存实例:定义一个private static成员变量存储类的实例(多个可用数组)先检测上面的成员 ...

  3. nginx服务的基本配置

    Nginx在运行时,至少必须加载几个核心模块和一个事件类模块.这些模块运行时所支持的配置项称为基本配置.由于配置项较多,所以把它们按照用户使用时的预期功能分为四类: 用于调试.定位问题的配置项 正常运 ...

  4. day 07 预科

    目录 异常处理 字符串内置方法 1.索引取值 2.切片 3.成员运算 4.for循环 5.len() 6.strip(): 默认去掉两端空格 7.lsteip()/rstrip(): 去左端/右端 空 ...

  5. union的使用

    将多条select语句的结果,合并到一起,称为联合查询 使用union关键字 场景: 获取数据的条件,出现逻辑冲突,或者很难在一个逻辑内表示,就可以拆成多个逻辑,分别实现,最后将结果合并到一起 sel ...

  6. ajax请求处理概要

    /** *不关心参数传递与参数返回的形式. */ url = ctxPath + '/ccb/xxx '; $.get(url); $.post(url); /** * 常见形式. */ var ur ...

  7. Linux 应用程序的安装和管理

    在Linux中,有三种安装软件的方式,分别是RPM包安装.YUM源安装.源代码编译安装. 常见应用程序目录结构 类型 路径 普通用户可执行文件 /usr/bin 管理员可执行文件 /usr/sbin ...

  8. Python的插件化开发概述

    Python的插件化开发概述 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.插件化开发 动态导入: 运行时,根据用户需求(提供字符串),找到模块的资源动态加载起来. 1> ...

  9. HTML常用全部代码--第一部分--HTML/CSS( 小伙伴要牢记😁😁😁😁 )

    <一>html代码大全:结构性定义 (1) 文件类型<HTML></HTML> (放在档案的开头与结尾) (2) 文件主题<TITLE></TIT ...

  10. js中的attribute详解

    Attribute是属性的意思,文章仅对部分兼容IE和FF的Attribute相关的介绍.attributes:获取一个属性作为对象getAttribute:获取某一个属性的值object.getAt ...