poj-1470
来源:互联网 发布:mac cs6破解方法 编辑:程序博客网 时间:2024/05/01 04:00
// 3452K 719MS C++#include <cstdio>#include <cstring>const int MAX = 910;struct TreeNode { int NextBroId; int parentId;};typedef struct TreeNode TreeNode;int LCACounter[MAX];int querys[MAX][MAX];int childListHead[MAX];int UF_Ancestor[MAX];int queryNum;int caseNum;int nodeNum;TreeNode tree[MAX];int ancestor[MAX];char fullyVisited[MAX];int querySolvedNum;void insertIntoChildList(int parentId, int childId) { tree[childId].parentId = parentId; int prevChildListHeadId = childListHead[parentId]; tree[childId].NextBroId = prevChildListHeadId; childListHead[parentId] = childId;}inline int UF_find(int nodeId) { // printf("UF_find %d\n", nodeId); int parentNodeUFId = nodeId; if (UF_Ancestor[parentNodeUFId] != parentNodeUFId) { UF_Ancestor[nodeId] = UF_find(UF_Ancestor[parentNodeUFId]); return UF_Ancestor[nodeId]; } else { return parentNodeUFId; }}inline void UF_Merge(int parentId, int childId) { int parentUFId = UF_find(parentId); int childUFId = UF_find(childId); UF_Ancestor[childUFId] = parentUFId; UF_Ancestor[childId] = parentUFId;}int DFSWithUF(int curNodeId) { // printf("DFSWithUF %d\n", curNodeId); UF_Ancestor[curNodeId] = curNodeId; // ancestor[curNodeId] = curNodeId; int curChildNodeId = childListHead[curNodeId]; while(curChildNodeId) { if (DFSWithUF(curChildNodeId)) { return 1; } UF_Merge(curNodeId, curChildNodeId); // ancestor[UF_find(curNodeId)] = curNodeId; curChildNodeId = tree[curChildNodeId].NextBroId; } // printf("%d is Ved\n", curNodeId); fullyVisited[curNodeId] = 1; for (int i = 1; i <= querys[curNodeId][0]; i++) { if (fullyVisited[querys[curNodeId][i]]) { int res = UF_Ancestor[UF_find(querys[curNodeId][i])]; LCACounter[res]++; // printf("FIND %d %d %d %d\n", curNodeId, // querys[curNodeId][i], res, UF_Ancestor[querys[curNodeId][i]]); querySolvedNum++; if (querySolvedNum == queryNum) { return 1; } } } return 0;}int main() { while(scanf("%d", &nodeNum) != EOF) { memset(childListHead, 0, sizeof(childListHead)); memset(tree, 0, sizeof(tree)); memset(UF_Ancestor, 0, sizeof(UF_Ancestor)); memset(LCACounter, 0, sizeof(LCACounter)); memset(querys, 0, sizeof(querys)); memset(fullyVisited, 0, sizeof(fullyVisited)); memset(ancestor, 0, sizeof(ancestor)); querySolvedNum = 0; for (int nodeId = 1; nodeId <= nodeNum; nodeId++) { int parentId; int childId; int childNum; scanf("%d", &parentId); // scanf("%s", nodeInfo); while(getchar() != '('); scanf("%d", &childNum); while(getchar() != ')'); // parentId = nodeInfo[0] - '0'; // int childNum = nodeInfo[3] - '0'; for (int j = 0; j < childNum; j++) { scanf("%d", &childId); // printf("%d Child %d\n", parentId, childId); insertIntoChildList(parentId, childId); } } scanf("%d", &queryNum); for (int i = 1; i <= queryNum; i++) { int A, B; while(getchar() != '('); scanf("%d%d", &A, &B); while(getchar() != ')'); querys[A][0]++; querys[A][querys[A][0]] = B; querys[B][0]++; querys[B][querys[B][0]] = A; } int rootNodeId = 0; for (int i = 1; i <= nodeNum; i++) { if (tree[i].parentId == 0) { rootNodeId = i; break; } } DFSWithUF(rootNodeId); for (int i = 1; i <= nodeNum; i++) { if (LCACounter[i] > 0) { printf("%d:%d\n", i, LCACounter[i]); } } }}
刚搞完1330以后趁热打铁, 原理一样,都是LCA, 只不过这次会有很多的query,因此,如果每次dfs都遍历所有的query的话,基本就TLE了,
因此要搞一个二维矩阵来标示query, query[i][j] 表示与 i 包含在相同query的 第j-1个(query[i][0]表示与i相关的query的数量)node的Id, 每次读入一个query,取到两个点A,B
就更新A 和 B的query矩阵,然后在dfs完某个点k以后,就只遍历query[k][1...N]就可以了,
这里还发现了之前的1330的一个错误,没有加dfs的访问标记vist[], 在每次dfs完某个点以后,就要标示已经visted, 然后下边判断是否是LCA的时候要用是否visted作为标准。
被注释掉的ancsteor数组是为了平衡并查集使用的,如果用平衡并查集的话,一个集合的root不一定就是 此集合在树中的根节点。不过如果不使用平衡并查集的话 ,而是直接根据树的结构来合并集合的话,就没有关系.
0 0
- poj-1470
- poj 1470--tarjan--LCA
- POJ 1470 LCA
- poj--1470--tarjan算法
- poj 1470(LCA)
- POJ 1470 Tarjan算法
- POJ
- poj
- POJ
- POJ
- poj
- poj
- POJ
- POJ
- poj
- POJ
- POJ
- POJ
- hdu 5017 Ellipsoid(西安网络赛 1011)
- NSArray使用小技巧
- 内存分析工具 MAT 的使用
- [UI]抽屉菜单DrawerLayout分析(一)
- eclipse 交叉编译 gcc g++ as的路径配置
- poj-1470
- CentOS服务器数据盘分区和格式化
- WeakHashMap理解
- How do I resolve unmet dependencies?
- 山东中医药大学计算机科学与技术2班王鑫童数据结构绪论笔记
- [UI]抽屉菜单DrawerLayout分析(二)
- 第一章 Oracle恢复内部原理(简介)
- 装饰精灵管理系统详细介绍
- opencv读取摄像头图像