图论
拓扑排序
#include <bits/stdc++.h> using namespace std; constexpr int N = 100010; int n, m, a, b; vector<int> e[N], tp; int din[N]; bool toposort(){ queue<int> q; for (int i = 1; i <= n; i++) if (din[i] == 0) q.push(i); while (q.size()){ int x = q.front(); q.pop(); tp.push_back(x); for (auto y : e[x]) { if(--din[y] == 0) q.push(y); } } return ((int)tp.size() == n); } int main(){ cin >> n >> m; for (int i = 0; i < m; i++) { cin >> a >> b; e[a].push_back(b); din[b]++; } if(!toposort()) cout << "Yes"; else cout << "No"; return 0; }
BellmanFord最短路
struct Edge{ int x, y, val; }edge[M+1]; int n, m, dist[M+1], pre[M+1]; int shortestPath(int s, int t){ memset(dist, 127, sizeof(dist)); dist[s]=0; bool ok=1; while(ok){ ok=0; for(int i=1;i<=m;i++){ int x = edge[i].x, y = edge[i].y, v = edge[i].val; if(dist[x] < (1<<30)){ if(dist[x] + v < dist[y]){ dist[y] = dist[x] + v; pre[y] = x; ok = 1; } } } } return dist[t]; }
Dijkstra最短路
struct edge{ int v, w; }; vector<edge> e[N]; int dist[N], vis[N]; priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> q; void dijkstra(int s, int n) { for (int i = 0; i <= n; i++) dist[i] = INF, vis[i] = 0; dist[s] = 0; q.push({dist[s], s}); while (q.size()) { auto t = q.top(); q.pop(); int u = t.second; if (vis[u]) continue; vis[u] = 1; for (auto ed : e[u]) { int v = ed.v, w=ed.w; if (dist[v] > dist[u] + w){ dist[v] = dist[u] + w; q.push({dist[v], v}); } } } }
Kruskal最小生成树
struct edge{ int u, v, w; bool operator< (const edge &t) const { return w < t.w; } }e[N]; int fa[N], ans, cnt; int find(int x){ if(fa[x] == x) return x; return fa[x] = find(fa[x]); } bool kruskal(){ sort(e, e + m); for(int i = 1; i <= n; i++) fa[i] = i; for(int i = 0; i < m; i++){ int x = find(e[i].u); int y = find(e[i].v); if (x != y) { fa[x] = y; ans += e[i].w; cnt++; } } return cnt == n - 1; }
Prim最小生成树
struct edge{int v,w;}; vector<edge> e[N]; int minTree,cnt; int d[N], vis[N]; priority_queue<pair<int,int>, vector<pair<int,int>>, greater<pair<int,int>>> q; bool prim(int s){ for(int i = 0; i <= n; i++) d[i] = INF; d[s] = 0; q.push({d[s],s}); while(q.size()){ int u=q.top().second; q.pop(); if(vis[u]) continue; vis[u]=1; minTree += d[u]; cnt++; for(auto ed : e[u]){ int v = ed.v, w=ed.w; if(d[v] > w){ d[v] = w; q.push({d[v], v}); } } } return cnt==n; }
强连通分量(tarjan)
vector<int> e[N]; int dfn[N], low[N], ins[N], bel[N], idx, n, m, cnt; stack<int> stk; vector<vector<int>> scc; void dfs(int u) { dfn[u] = low[u] = ++idx; ins[u] = 1; stk.push(u); for(auto v : e[u]){ if(!dfn[v]){ dfs(v); low[u] = min(low[u], low[v]); }else{ if(ins[v]) low[u] = min(low[u], dfn[v]); } } if(dfn[u] == low[u]){ vector<int> c; ++cnt; while(true){ int v = stk.top(); c.push_back(v); ins[v] = false; bel[v] = cnt; stk.pop(); if(v == u) break; } sort(c.begin(), c.end()); scc.push_back(c); } }
强连通分量(kasaraju)
vector<int> e[N], erev[N]; int dfn[N], low[N], ins[N], bel[N], idx, n, m, cnt; bool vis[N]; stack<int> stk; vector<vector<int>> scc; vector<int> out, c; void dfs(int u){ vis[u]=true; for(auto v : e[u]){ if(!vis[v]) dfs(v); } out.push_back(u); } void dfs2(int u){ vis[u]=true; for(auto v : erev[u]){ if(!vis[v]) dfs2(v); } c.push_back(u); } void work() { for (int i=1; i<=n; i++) { if(!vis[i]) dfs(i); } reverse(out.begin(), out.end()); memset(vis, 0, sizeof(vis)); for(auto u : out) if(!vis[u]) { c.clear(); dfs2(u); scc.push_back(c); } } int main(){ ios::sync_with_stdio(0); cin.tie(0); cin >> n >> m; for (int i = 0; i < m; i++) { int u,v; cin >> u >> v; e[u].push_back(v); erev[v].push_back(u); } work(); return 0; }
割边
vector<array<int, 2>> e[N]; int dfn[N], low[N], idx, n, m; vector<int> bridge; void dfs(int u, int id) { dfn[u] = low[u] = ++idx; for(auto z : e[u]){ v = z[0], id2 = z[1]; if (!dfn[v]) dfs(v, id2); if (id != id2) low[u] = min(low[u], low[v]); } if(dfn[u] == low[u] && id != -1){ bridge.push_back(id + 1); } } //dfs(1, -1)
割点
vector<int> e[N]; int dfn[N], low[N], idx, n, m, sz; bool cut; void dfs(int u, int f) { dfn[u] = low[u] = ++idx; int ch = 0; for(auto v : e[u]){ if (!dfn[v]) { dfs(v, u); ch++; low[u] = min(low[u], low[v]); if (low[u] >= dfn[u]) cut[u] = 1; } else if (v != f) { low[u] = min(low[u], low[v]); } } if(u == 1 && ch <= 1){ cut[u] = 0; } sz += cut[u]; } //dfs(1, 0)
二分图
#include<bits/stdc++.h> using namespace std; constexpr int N = 1100; vector<int> edge[N+1]; int n, m, c[N + 1]; bool dfs(int x){ for(auto y : edge[x]){ if(!c[y]) { c[y] = 3 - c[x]; if(!dfs(y)){ return false; } } else { if(c[x] == c[y]) return false; } } return true; } bool check(){ memset(c, 0 ,sizeof c); for (int i = 1; i <= n; i++) { if (!c[i]) { c[i] = 1; if (!dfs(i)) return false; } } return true; } int main(){ ios::sync_with_stdio(0); cin.tie(0); cin>>n>>m; for(int i = 1; i <= m; i++){ int u, v; cin>>u>>v; edge[u].push_back(v); edge[v].push_back(u); } if(check()){ cout<<"Yes"; }else{ cout<<"No"; } return 0; }
二分图最大匹配
int n, m; vector<int> e[N+1];//L to R int n1, n2, v[N+1]; bool b[N+1]; bool find(int x){ b[x] = true; for(auto y : e[x]){ if(!v[y] || (!b[v[y]]&&find(v[y]))){ v[y] = x; return true; } } return false; } int match(){ int ans = 0; memset(v, 0, sizeof(v)); for(int i = 1; i <= n1; i++){ memset(b, false, sizeof(b)); if(find(i)) ++ans; } return ans; }

浙公网安备 33010602011771号