COMMENTShtml
標題 | 做者 | 日期 | |
---|---|---|---|
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] |