转载自:http://cojs.tk/cogs/page/page.php?aid=30
- 最小生成树
- Kruskal+ufs
-
1 int ufs(int x){ 2 return f[x] == x ? x : f[x] = ufs(f[x]); 3 } 4 int Kruskal(){ 5 int w = 0; 6 for(int i=0; i<n; i++) 7 f[i] = i; 8 sort(e, e+n); 9 for(int i=0; i<n; i++){ 10 int x = ufs(e[i].u), y = ufs(e[i].v); 11 if(x != y) { 12 f[x] = y; 13 w += e[i].w; 14 } 15 } 16 return w; 17 }
- Prim
1 int Prim() { 2 int w = 0; 3 priority_queue<pair<int, int> > q; 4 bool l[N] = {0}; 5 l[1] = 1; q.push(make_pair(0, 1)); 6 for(int k=1; k<n; k++) { 7 int u = q.top().second; q.pop(); 8 for(int i=0; i<G[u].size(); i++) 9 if(!l[G[u][i]]) 10 q.push(make_pair(-c[u][i], G[u][i])); 11 while(!q.empty() && l[q.top().second]) 12 q.pop(); 13 l[q.top().second] = 1; 14 w += -q.top().first; 15 q.pop(); 16 } return w; }
- 最短路径
- Dijkstra+priority_queue
1 void Dijkstra(int s) { 2 priority_queue<pair<int, int> > q; 3 bool l[N] = {0}; l[s] = 1; 4 fill_n(f, n, INF); f[s] = 0; 5 q.push(make_pair(-f[s], s)); 6 while(!q.empty()) { 7 int u = q.front().second; q.pop(); 8 for(int i=0; i<G[u].size(); i++) { 9 int v = G[u][i]; 10 if(f[v] > f[u] + c[u][i]) { 11 f[v] = f[u] + c[u][i]; 12 if(!l[v]) { 13 l[v] = 1; 14 q.push(make_pair(-f[v], v)); 15 } 16 } 17 } 18 } }
- Bellman-Ford (SPFA)
1 void BellmanFord(int s) { // SPFA 2 queue<int> q; 3 bool l[N] = {0}; l[s] = 1; 4 fill_n(f, n, INF); f[s] = 0; 5 q.push(s); 6 while(!q.empty()) { 7 int u = q.front(); q.pop(); 8 l[u] = 0; 9 for(int i=0; i<G[u].size(); i++) { 10 int v = G[u][i]; 11 if(f[v] > f[u] + c[u][i]) { 12 f[v] = f[u] + c[u][i]; 13 if(!l[v]) { 14 l[v] = 1; 15 q.push(v); 16 } 17 } 18 } 19 } }
- Floyd
1 void Floyd() { 2 for(int k=0; k<n; k++) 3 for(int i=0; i<n; i++) 4 for(int j=0; j<n; j++) 5 f[i][j] = min(f[i][j], f[i][k] + f[k][j]); }
- 二分图
- ufs 验证 Hungary
1 bool DFS(int u) { 2 for(int i=0; i<G[u].size(); i++) { 3 int v = G[u][i]; 4 if(!l[v]) { 5 l[v] = 1; 6 if(!f[v] || DFS(f[v])) { 7 f[v] = u; 8 return true; 9 } 10 } 11 } return false; } int Hungary() { 12 int w = 0; 13 for(int i=0; i<n; i++) { 14 fill_n(l, l+n, 0); 15 if(DFS(i)) 16 w++; 17 } return w; }
- 连通分量
- Tarjan stack
1 <int> s; void Tarjan(int u) { 2 dfn[u] = low[u] = ++time; 3 l[u] = 1; 4 s.push(u); 5 for(int i=0; i<G[u].size(); i++) { 6 int v = G[u][i]; 7 if(!dfn[v]) { 8 Tarjan(v); 9 low[u] = min(low[u], low[v]); 10 } else if(l[v]) 11 low[u] = min(low[u], dfn[v]); 12 } 13 if(dfn[u] == low[u]) { 14 w++; 15 do {int v; 16 l[v = s.top()] = 0; 17 f[v] = w; 18 s.pop(); 19 } while(u != v); 20 } } void SCC() { 21 fill_n(dfn, n, 0); 22 for(int i=0; i<n; i++) 23 if(!dfn(i)) 24 Tarjan(i); }
- 网络流
- 费用流:Bellman-Ford 找增广路,或者用贪心求解
- 最大流:Edmonds-Karp