宜中資訊
CP
Ccucumber12
2021.08.20
consider the two/four edges' performance
a | b | c | d | e | f | g | h | |
---|---|---|---|---|---|---|---|---|
dep | 0 | 1 | 2 | 3 | 4 | 2 | 3 | 2 |
low | 0 | 0 | 1 | 1 | 2 | 2 | 3 | 0 |
const int N = 100010 ; vector<int> g[N]; bool vis[N], bridge[N] ; int low[N], dep[N] ; void dfs(int x) { vis[x] = true ; low[x] = dep[x] ; for(auto i:g[x]) { if(vis[i]) { low[x] = min(low[x], dep[i]) ; } else { dep[i] = dep[x] + 1 ; dfs(i) ; low[x] = min(low[x], low[i]) ; } } if(low[x] == dep[x]) bridge[x] = true ; }
const int N = 100010 ; vector<int> g[N]; bool vis[N], bridge[N] ; int low[N], dep[N], bcc[N], bccID ; stack<int> stk ; void dfs(int x) { vis[x] = true ; low[x] = dep[x] ; stk.push(x) ; for(auto i:g[x]) { if(vis[i]) { low[x] = min(low[x], dep[i]) ; } else { dep[i] = dep[x] + 1 ; dfs(i) ; low[x] = min(low[x], low[i]) ; } } if(low[x] == dep[x]) { bridge[x] = true ; ++bccID ; int k ; do { k = stk.top() ; bcc[k] = bccID ; stk.pop() ; } while(k != x) ; } }
const int N = 100010 ; vector<int> g[N], rg[N], ord; int scc[N], sccID ; bool vis[N] ; void dfsRev(int x) { vis[x] = true ; for(auto i:rg[x]) if(!vis[i]) dfsRev(i) ; ord.push_back(x) ; } void dfs(int x) { vis[x] = true ; scc[x] = sccID ; for(auto i:g[x]) if(!vis[i]) dfs(i) ; } void kosaraju(int n) { for(int i=1; i<=n; ++i) if(!vis[i]) dfsRev(i) ; reverse(ord.begin(), ord.end()) ; fill(vis, vis+N, 0) ; for(auto i:ord) if(!vis[i]) { ++sccID ; dfs(i) ; } }
const int N = 1010 ; vector<int> g[N]; int py[N] ; bool vis[N] ; bool dfs(int x) { for(auto i:g[x]) if(!vis[i]) { vis[i] = true ; if(!py[i] || dfs(py[i])) { py[i] = x ; return true ; } } return false ; } int APA(int n) { int ret = 0 ; for(int i=1; i<=n; ++i) { fill(vis, vis+N, 0) ; if(dfs(i)) ++ret ; } }
一般
struct KM { int n ; vec<vec<pii>> g ; vec<int> lx, ly, vx, vy, p; KM (int _n) { n = _n ; g.rs(n + 1) ; p.rs(n + 1) ; lx.rs(n + 1) ; ly.rs(n + 1) ; vx.rs(n + 1) ; vy.rs(n + 1) ; } void addEdge(int a, int b, int c) { g[a].EB(b, c); } bool dfs(int x) { vx[x] = true; for(auto [i, u]:g[x]) if(!vy[i] && lx[x] + ly[i] == u) { vy[i] = true; if(!p[i] || dfs(p[i])) { p[i] = x ; return true; } } return false ; } int exe () { rep1(i, n) for(auto j:g[i]) amax(lx[i], j.S); rep1(i, n) { while(true) { fill(ALL(vx), 0); fill(ALL(vy), 0); if(dfs(i)) break; int d = INF; rep1(i, n) if(vx[i]) for(auto [j, u]:g[i]) if(!vy[j]) amin(d, lx[i] + ly[j] - u) ; rep1(i, n) { if(vx[i]) lx[i] -= d ; if(vy[i]) ly[i] += d ; } } } int ret = 0; rep1(i, n) ret += lx[i] + ly[i] ; return ret ; } };
優化
struct KM { int n; vec<vec<int>> g; vec<int> lx, ly, slk, vis, pre, mat; KM (int _n) { n = _n ; g.assign(n+1, vec<int>(n+1, -INF)); lx.rs(n+1); ly.rs(n+1); vis.rs(n+1); mat.rs(n+1); slk.rs(n+1); pre.rs(n+1); } void addEdge(int a, int b, int c) { g[a][b] = c; } void bfs(int x) { int px, py = 0, ny = 0, d; rep(i, n+1) vis[i] = pre[i] = 0, slk[i] = INF; mat[py] = x; do { px = mat[py], vis[py] = true, d = INF; rep1(i, n) if(!vis[i]) { if(slk[i] > lx[px] + ly[i] - g[px][i]) slk[i] = lx[px] + ly[i] - g[px][i], pre[i] = py; if(d > slk[i]) d = slk[i], ny = i; } rep(i, n+1) if(vis[i]) lx[mat[i]] -= d, ly[i] += d; else slk[i] -= d; py = ny; } while(mat[py]); while(py) mat[py] = mat[pre[py]], py = pre[py]; } ll match() { rep1(i, n) bfs(i); ll ret = 0; rep1(i, n) ret += lx[i] + ly[i]; return ret; } };