评论备份(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]
posted @ 2018-05-26 10:57  headchen  阅读(101)  评论(0编辑  收藏  举报