BZOJ 2657 (ZJOI 2012 旅游) 求树上最长链(树的直径) MAP建树+BFS/DFS
来源:互联网 发布:詹姆斯本赛季数据 编辑:程序博客网 时间:2024/06/06 08:41
这道题是挺简单,求树上一条最长的路径(后来才知道这叫树的直径),而麻烦的是如何建树,这是这道题略恶心的地方。
数据的给出方式是每个节点给3个值(1~n),如果两个节点间有两个值相同,那么这两个点就是有一条边相连。题目中的描述什么凸多边形,三角形的顶点什么的一开始看确实被吓到了,其实就是两个三角形如果有公共边,那么这三角形代表的节点之间就有一条边,三角形的三个顶点就是前面所说的三个值。又因为整个图是凸多边形,也就是说三角形的顶点不会在内部出现,那么就是说不会有环的存在,而且整个图是一个连通的,又因为一共有n个顶点,会形成n-2个三角形,也就是说有n-2个节点,每个节点的三个值都是1~n之间的数,所以可以推得一共有n-3条边。n-2个节点,n-3条边,无环,连通,所以这是棵树。
那么我们怎么建树呢?——通过已有的每个节点的3个值。因为树边是需要两个值相等,所以我们需要记录两个值,如现在输入一个节点的三个值a,b,c,我们需要判断(a,b), (b,c), (a,c)是否存在,如果存在,就把存在的那个节点与当前结点连边,不存在则记录为存在。因为输入的三个值是无序的,而且边的存在性也不需要两个值顺序固定,所以我们要把a,b,c排序,避免明明存在(a,c)却因为当前输入顺序是(c,a)而判定为不存在。那么记录(a,b)这样的一个数对存在用二维数组会爆内存,不过我们可以想到STL里的MAP。定义一个<pair<int,int>, int>型的map,pair是数对,int是这个数对存在的节点,因为边是以相邻的三角形的公共边产生的,所以不用担心一个数对会出现3次或3次以上。
有了树,求直径:先以任意一个点为根BFS/DFS,找出距离最远的点,再以那个距离最远的点为根BFS/DFS,这次再求出来最远的点,这两个点的距离就是所求的最长路径了。BFS/DFS很好写,相当于裸题了。
#include <cstdio>#include <algorithm>#include <cstring>#include <map>#include <cstdlib>#include <vector>#define M 200002using namespace std;int n, p, d;vector <int> G[M];map <pair<int, int>, int> m;pair <int, int> t;void init(){int a[3];scanf("%d", &n);for(int i = 1; i < n-1; i++){scanf("%d %d %d", a, a+1, a+2);sort(a, a+3);t = make_pair(a[0], a[1]);if(m[t]) G[i].push_back(m[t]), G[m[t]].push_back(i);else m[t] = i;t = make_pair(a[0], a[2]);if(m[t]) G[i].push_back(m[t]), G[m[t]].push_back(i);else m[t] = i;t = make_pair(a[1], a[2]);if(m[t]) G[i].push_back(m[t]), G[m[t]].push_back(i);else m[t] = i; }}void dfs(int u, int fa, int dis){if(dis > d) p = u, d = dis;for(int i = 0; i < G[u].size(); i++){int v = G[u][i];if(v == fa) continue;dfs(v, u, dis+1);}}int main(){init();dfs(1, 0, 1);dfs(p, 0, 1);printf("%d", d);}
- BZOJ 2657 (ZJOI 2012 旅游) 求树上最长链(树的直径) MAP建树+BFS/DFS
- BZOJ 2657 ZJOI 2012 旅游(journey) 树的直径
- bzoj 2657: [Zjoi2012]旅游(journey) (map建图+树的直径)
- BZOJ3124 [sdoi2013]直径(树上的dfs)
- 树的直径 (树上的最长路)
- 求树的直径(最长路径)
- HOJ 1030 Labyrinth----------------两次BFS求树的直径(图的最长路)
- 【BZOJ1912】【Apio2010】巡逻 树上最长链(才不是树的直径呢)
- [BZOJ 2657][Zjoi2012]旅游(journey):树的直径
- CSU oj 1681 Adjoin(dfs求树上最长路径)
- 2015 ACM Amman Collegiate Programming Contest H.Bridges【边双联通+求树上最长链(树的直径)】
- 【 LightOJ - 1094】Farthest Nodes in a Tree(求树的直径)链式向前星 + DFS or BFS
- BFS求树的直径
- Cow Marathon(两次dfs求树的直径)
- 蓝桥杯 历届试题 大臣的旅费 (两次dfs 之树上求最长路径)
- HDU_2196_Computer(树上节点的最长路径 · dfs / bfs)
- POJ 1985 Cow Marathon(两次BFS求树的直径(最长路))
- bzoj 3124: [Sdoi2013]直径 (dfs)
- postgresql 按日期范围查询
- Linux系统下如何SSH免密码登录
- Java SimpleDateFormat 中英文时间格式化转换
- 如何利用block进行回调
- Python中的编码问题
- BZOJ 2657 (ZJOI 2012 旅游) 求树上最长链(树的直径) MAP建树+BFS/DFS
- CString简单介绍及使用
- HDU 1010 搜索剪枝
- NAND FLASH控制器
- 求二叉树的镜像
- 使用cargo实现jenkins自动部署远程tomcat
- 分享四
- Linux忘记root密码解决办法
- pat 1001. A+B Format