评论备份(2)
COMMENTS
标题 | 作者 | 日期 | |
---|---|---|---|
Re:luogu2398 SUM GCD | headchen | 2018-04-24 10:31 | |
但这个不是【正解】,因为算法复杂度是O(n)logn的,测试数据一强就不行了。 | |||
Re:POJ1144 Network 无向图割点 | headchen | 2018-03-30 16:32 | |
尽管你这个能够通过,但是有bug [code=cpp] void Dfs(Node *u) { if (u->DfsN) return; u->DfsN = u->Low = ++DfsCnt; int cnt = 0; for (Edge *e = u->Head; e; e = e->Next) { if (!e->To->DfsN) { Dfs(e->To); u->Low = min(u->Low, e->To->Low); if (u!=Root && u->DfsN <= e->To->Low || u == Root && ++cnt > 1 ) //应该放到这里, 因为是统计【子节点】个数并加以判断 { //cnt++; //不应该放到这里 // if (u != Root || cnt > 1) u->IsCut = true; } } else u->Low = min(u->Low, e->To->DfsN); } } [/code] |
|||
Re:POJ1144 Network 无向图割点 | headchen | 2018-03-30 14:02 | |
【算法的目的】 在一个【无向图】中,如果删掉点 v 后图的【连通块】数量增加,则称点 v 为图的割点。 【定义】 dfn(u): 表示进入节点 u 时的时间。 low(u): 表示由节点 u 开始搜索所能到达的点中,在搜索树上是 u 的祖先且 dfn 最小的节点的 dfn。 【算法描述】 类似于 Tarjan 求强连通分量的算法。 从起点开始 DFS; 1. 进入一个节点时,初始化它的 dfn 和 low 均为当前时间戳; 2. 枚举当前点 v v 的所有邻接点; 3. 如果某个邻接点 u 已被访问过,则更新 low(v) = min(low(v), dfn(u)) low(v)=min(low(v),dfn(u)); 4. 如果某个邻接点 u 未被访问过,则对 u 进行 DFS,并在【回溯】后更新 low(v)=min(low(v),low(u)); 5. ①对于一个搜索树上的非根节点 u,如果存在子节点 v,满足 low(v)≥dfn(u),则 u 为割点; ②对于根节点,如果它有两个或更多的子节点,则它为割点。 【解释】 “对于根节点,如果它有两个或更多的子节点,则它为割点” 显然,根是两棵子树上节点的唯一连通方式。 对于一个搜索树上的非根节点 u,如果存在子节点 v,满足 low(v)≥dfn(u),则 u 为割点; low(v)≥dfn(u) 的意义是, v 向上无法到达 u 的父节点。 |
|||
Re:luogu3384 【模板】树链剖分 | headchen | 2018-03-29 10:57 | |
学习了。 建议: [code=cpp] // void UpdatePath(Node *u, Node *v, int value) void UpdatePath(Node *high, Node *low, int value) [/code] 这样更加清晰,QueryPath也是一样 |
|||
Re:HDU2255 奔小康赚大钱 【模板】二分图完美匹配 | headchen | 2018-03-29 10:46 | |
这样可以 [code=cpp] int delta = INF; LOOP(y, _yCnt) //比原来少了一层循环 if (!Yvis[y]) delta = min(delta, Delta[y]); [/code] 少一层循环。降低时间[复杂度]一个量级。 |
|||
Re:HDU2255 奔小康赚大钱 【模板】二分图完美匹配 | headchen | 2018-03-29 10:43 | |
关于【最小松弛量delta】,定义各个delta[MAXN],可以在findPath中【维护】,当找不到时,直接取最小即可。这样可以是的时间复杂度从O(N^4)降低到 O(N^3)。 [code=cpp] bool FindPath(int x) { Xvis[x] = true; LOOP(y, _yCnt) { if (Yvis[y]) continue; int d = Xl[x] + Yl[y] - XYweight[x][y]) if(d==0) //易忘点:相等子图 { Yvis[y] = true; if (!YmatchX[y] || FindPath(YmatchX[y])) { YmatchX[y] = x; return true; } } else Delta[y] = min(Delta[y],d); //顺便维护了Delta,到了用时可以少一层循环 } return false; } [/code] |
|||
Re:HDU2255 奔小康赚大钱 【模板】二分图完美匹配 | headchen | 2018-03-29 10:37 | |
学习了。 描述可以简洁一些: 1. 初始化【顶标】 2. 在【相等子图】中找【交错路】。 3. 若没有找到,则以【最小松弛量delta】【修改】【顶标】,使得【相等子图】中“至少”【增加】一条边。若失败,则意味着不存在完美匹配。 4. 重复2,3。 |
|||
Re:luogu3379 【模板】最近公共祖先(LCA) 倍增法 | headchen | 2018-03-27 10:04 | |
for (int i = log2(a->Depth-b->Depth); i >= 0; i--) if (a->Elder[i] && a->Elder[i]->Depth >= b->Depth) a = a->Elder[i]; 可以用下面的代码替换更好: for(int i =0;i<= log2(a->Depth-b->Depth);i++) if((1<<i)&b) //(1<<i)&b可以判断b的二进制表示中,第i位上是否为1 a = a->Elder[i]; //把i往上提 |
|||
Re:luogu3379 【模板】最近公共祖先(LCA) 倍增法 | headchen | 2018-03-27 08:55 | |
写的很好, 建议: Node *Lca(Node *a, Node *b) -》 Node *Lca(Node *high,Node *low) 好的命名可以减少一半的bug |
|||
Re:排列、组合、枚举子集 | headchen | 2018-03-26 15:32 | |
学习了。 但是:「全排列」确有更加简洁的算法: [code=cpp] void Perm(int list[],int k,int m) { if(k==m) ;// 输出 else { // for(int j=k;j<=m;j++) { swap(list[k],list[j]); Perm(list,k+1,m); swap[list[k],list[j]); } } } [/code] |