學習部落格
那些年我用帶花樹做過的題目:
帶花樹板子
#include
using
namespace std;
const
int n =
1200+10
;int n, m, k;
inline
intread()
namespace flowertree e[
(300
*600)*
6+10]
;int head[n]
, tot =1;
int fa[n]
;//fa[i] 記錄i點屬於哪乙個點為根的花
int pre[n]
;//pre[i] i的前驅節點
queue<
int> q;
//int q[n * n * 2], h, t;//bfs佇列 頭尾
int match[n]
;//match[i]標記匹配的物件
int tim;
//lca時間戳
int type[n]
;//type[i]標記i點的型別 奇節點:1 偶節點:2 沒有標記過時為0
int dfn[n]
;//每個節點的lca時間戳
void
addedge
(int u,
int v)
; head[u]
= tot;
e[++tot]=;
head[v]
= tot;
}int
find
(int x)
intlca
(int x,
int y)
return x;
}// 開花操作
// 將奇環縮成乙個點 並將原來奇點的點變為偶點 並加入佇列中
void
blossom
(int x,
int y,
int p)
fa[x]
= p;
fa[y]
= p;
x = pre[y];}
}bool
aug(
int st)
while
(!q.
empty()
)q.pop()
;//------------------
q.push
(st)
; type[st]=1
;//標記為奇點
while
(!q.
empty()
)return
true;}
//如果有匹配 則v是偶點 將v匹配的物件放入佇列中
type[match[v]]=
1;//q[t++] = match[v];
q.push
(match[v]);
}else
if(type[v]==1
)}}return
false;}
void
init()
}using
namespace flowertree;
intmain()
}int res =0;
for(
int i =
1; i <= flowertree_n; i++)}
printf
("%d\n"
, res - n);}
return0;
}
筆記 帶花樹
帶花樹用來解決一般圖的最大匹配問題。考慮不能直接增廣的原因是存在奇環。帶花樹的思路是把奇環給縮成一朵花。然後仍然通過增廣路演算法實現擴大匹配數目。其中能縮成一朵花的原因是。一堆點縮成花之後能夠成為增廣路中的某乙個點,那麼原圖也可以。這樣就簡化了模型從而可以直接用 bfs 增廣。1.uoj79 模板題...
帶花樹總結
匈牙利演算法 二分圖最大匹配 考慮一下二分圖和一般圖的最大區別 或者說唯一的區別在 二分圖沒有奇環 也就是長度為奇數的環 而一般圖是可以有的。所以匈牙利演算法中的尋找增廣路然後路徑取反的方法在一般圖上就不適用了。主要還是要解決奇環的問題。我們發現乙個奇環裡至少有乙個點不能匹配,那就乾脆把乙個奇環縮成...
帶花樹草解
這個東西其實看看就好,n 3 次的做法雖說也是多項式複雜度但總給人很暴力的感覺.我們都知道二分圖最大匹配可以匈牙利 網路流,因為二分圖只有一邊連向另一邊,換句話說就是不存在奇環 可以簡單證明 這是增廣路演算法可以解決的 對於有向無環圖,網路流演算法也可以跑得非常優秀,但是對於一般圖來說,這兩個演算法...