题目地址

hdu5438

题干

代码和解释

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

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

#include<iostream>
#include<vector>
using namespace std;
int main()
{
vector<int> n[100];
int i;
for(i=0;i<100;i++){
n[i].clear();
}
n[5].push_back(1);
n[5].push_back(3);
printf("%d\n",n[5].size());//为2
printf("%d\n",n[5][0]);//为1
printf("%d\n",n[5][1]);//为3
//printf("%d\n",n[5]);//编译不通过
return 0;
}

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

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

这里是c++代码。

#include<iostream>
#include<vector>
#include<cstring>
#include<cstdio>
using namespace std;
int v[10010],f[10010],l[10010];//v存储每个池塘的值,f存储其是否被遍历过,l存储每个池塘连接管子数
vector<int> x[10010];//x存储每个池塘与哪个池塘相连的具体情况
int tmp;//tmp是已经遍历的节点个数
long long sum1,sum2;
void dfs(int t);
int main()
{
int T,p,m,a,b;//T为样例组数,p为池塘数,m为连接组合数,a、b为每组连接中两个池塘的位置(编号)
int i,j;
int flag;
scanf("%d",&T);
while(T--){
scanf("%d%d",&p,&m);
sum1=0;
memset(v,0,sizeof(v));
memset(f,0,sizeof(f));
memset(l,0,sizeof(l));//初始化
for(i=0;i<10010;i++){
x[i].clear();//初始化
}
for(i=1;i<=p;i++){//从1开始到p结束,不然会错,因为a和b存储位置是从1开始的
scanf("%d",&v[i]);
}
for(i=0;i<m;i++){
scanf("%d%d",&a,&b);
x[a].push_back(b);//a与b相连
x[b].push_back(a);//b与a相连
l[a]++;//与a相连的池塘(管子)数加1
l[b]++;//与b相连的池塘(管子)数加1
}
flag=1;
while(flag==1){
flag=0;//如果所有剩下的池塘连接管子数都大于等于2,则flag就会保持为0
for(i=1;i<=p;i++){//i从1开始到p
if(l[i]==0||l[i]==1){
//连接管子数小于2
flag=1;//只要这样的池塘还存在,就让flag为1,重新执行循环
f[i]=1;//表示已经遍历过
for(j=0;j<x[i].size();j++){//x[i].size表示位置为i的这个池塘连接的管子数
l[x[i][j]]--;//让所有与位置为i的池塘相连的池塘的连接管子数减1,即删除了位置为i的池塘与其他池塘的连接关系
}
l[i]=-1;//表示连接管子数小于2
}
}
}
//这样处理完后就只剩下连接管子数大于等于2的池塘,接下来用dfs判断每个连接组合是否包含奇数个池塘
for(i=1;i<=p;i++){//i从1开始到p
if(f[i]==0){
//说明是还没有遍历过的
sum2=0;
tmp=0;
dfs(i);//经过这个操作,tmp变成这个组合中池塘的数量,sum2变成这个组合中所有池塘值的和,并且这个组合中所有池塘都被遍历过了
if(tmp%2==1){//如果包含奇数个池塘
sum1+=sum2;
}
}
}
printf("%lld\n",sum1);
}
return 0;
}
void dfs(int t){
int i;
tmp++;
f[t]=1;//表示已经遍历过,这样就不会对同一个组合中的每个池塘多次计算了
sum2+=v[t];//加上这个池塘的值
for(i=0;i<x[t].size();i++){
if(f[x[t][i]]==0){//对于与这个池塘相连的所有未被遍历过的池塘
dfs(x[t][i]);
}
}
return;
}

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

参考

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. 模仿jquery--offset方法。原生JS获取任意元素到文档document顶部的距离

    1.通过遍历目标节点.目标节点的父节点,依次溯源. 然后累加这些节点到其最近可定位的祖先节点的距离.向上直到document. 其中,需要使用到节点的offsetTop/offsetLeft属性,来获 ...

  2. 关于Python学习之 列表与字典

    列表 列表是Python中最具灵活性的有序集合对象类型. # 列表迭代和解析 >>> res = [c*4 for c in 'Spam'] >>> res ['S ...

  3. 笔谈HTTP Multipart POST请求上传文件

    公司一做iOS开发的同事用HTTP Multipart POST请求上传语音数据,但是做了两天都没搞定,项目经理找到我去帮忙弄下.以前做项目只用过get.post,对于现在这个跟服务器交互的表单请求我 ...

  4. 关于服务器程序运行中收到SIGPIPE(转)

    (此文为原文删减版,原文地址:http://blog.sina.com.cn/s/blog_502d765f0100kopn.html) 我写了一个服务器程序,在Linux下测试,然后用C++写了客户 ...

  5. linux下svn解决冲突

    1. 使用svn status + 文件路径+文件名 查看文件或目录的状态(该状态可自行进行百度),属性状态为'C'的表示,改文件或目录处于冲突状态 2. 使用svn resolve --accept ...

  6. 如何使用GUID硬盘分区格式安装新windows系统

    全局唯一标识分区表(GUID Partition Table,缩写:GPT)是一个实体硬盘的分区结构.目前硬盘格式有两种,一种MBR,另一个就是GUID.一般电脑买过来是windows7以上,比如wi ...

  7. hbase完整分布式集群搭建

    简介: hadoop的单机,伪分布式,分布式安装 hadoop2.8 集群 1 (伪分布式搭建 hadoop2.8 ha 集群搭建 hbase完整分布式集群搭建 hadoop完整集群遇到问题汇总 Hb ...

  8. C# 认识 接口

    一.什么是接口 C#接口中包含方法.属性.索引器和事件的声明,但常用的接口中一般就是方法和属性,然而接口中并没有方法的具体实现代码(不能提供任何成员实现),只有方法的返回类型和方法名.一个类实现了某个 ...

  9. Oracle 11g RAC to RAC ADG搭建(一)采用rman备份恢复方式

    (一)基础环境   主库 备库 操作系统 RedHat6.7 RedHat6.7 服务器名称 primarydb1primarydb2 standbydb1standbydb2 IP地址规划 192. ...

  10. H3C 802.11n的频宽模式