模版(1)

模版

图论相关:

Dijkstra


int n, m, dis[N];
bool vis[N];
vector<pair<int, int>> e[N];
inline void dij(int s){
	priority_queue<pair<int, int>> q1;
	q1.push({0, s});
	memset(dis, 0x3f, sizeof dis);//初始化为极大值
	memset(vis, 0, sizeof vis);
	dis[s] = 0;
	while(q1.size()){
		int x = q1.top().second;
		q1.pop();
		if(vis[x]){
			continue;
		}
		vis[x] = 1;
		for(const auto o : e[x]){
			int tx = o.first, ty = o.second;
			if(dis[tx] > dis[x] + ty){
				dis[tx] = dis[x] + ty;
				q1.push({-dis[tx], tx});
			}
		}
	}
}

SPFA


判负环:

int cnt[N], dis[N], n, m;
bool vis[N];
vector<pair<int, int>> e[N];
inline bool spfa(){
	queue<int> q;
	memset(dis, 0x3f, sizeof dis);//别忘初始化
	memset(cnt, 0, sizeof cnt);
	for(int i = 1; i <= n; ++i){
		q.push(i);
		vis[i] = 1;
	}
	while(q.size()){
		int x = q.front(); q.pop();
		vis[x] = 0;
		for(const auto o : e[x]){
			int tx = o.first, ty = o.second;
			if(dis[tx] > dis[x] + ty){
				dis[tx] = dis[x] + ty;
				cnt[tx] = cnt[x] + 1;
				if(cnt[tx] == n){
					return true;//有负环
				}
				if(!vis[tx]){
					vis[tx] = 1;
					q.push(tx);
				}
			}
		}
	}
	return false;//没负环
}

判正环:

1.边权全取相反数 直接跑判负环

2.跑最长路 cnt[x] >= n就有正环

Floyd(n<=500)


int dis[100][100];
for(int k = 1; k <= n; ++k){
    for(int i = 1; i <= n; ++i){
        for(int j = 1; j <= n; ++j){
            dis[i][j] = min(dis[i][j], dis[i][k] + dis[k][j]);
        }
    }
}

先使dis[i][i] = 0

ij 之间有边,则 dis[i][j] = weight[i -> j] 否则直接赋值正无穷

Kruscal(MST)


int fa[N], m, n, ans;
struct node{
	int u, v, w;
}e[N];
inline int getf(int x){ return fa[x] == x ? x : fa[x] = getf(fa[x]); }
int cnt;
inline void kruscal(){
	for(int i = 1; i <= n; ++i){
		fa[i] = i;
	}
	for(int i = 1; i <= m; ++i){
		int tx = getf(e[i].u), ty = getf(e[i].v), tw = e[i].w;
		if(ty != tx){
			fa[tx] = ty;
			ans += tw;
			if(++cnt == (n - 1)){
				return;
			}
		}
	}
}
main(){
	n = read(), m = read();
	for(int i = 1; i <= m; ++i){
		e[i].u = read(), e[i].v = read(), e[i].w = read();
	}
	stable_sort(e + 1, e + 1 + m, [&](node aa, node bb){return aa.w < bb.w; });
	kruscal();
}

Prim


不会 以后学吧

Tarjan(割点)


int n, m, dfn[N], low[N];
vector<int> e[N];
int tmp;
bool is[N];
int root;
inline void tarjan(int x){
	dfn[x] = low[x] = ++tmp;
	int tree = 0;
	for(const auto o : e[x]){
		if(!dfn[o]){
			tarjan(o);
			low[x] = min(low[x], low[o]);
			if(low[o] >= dfn[x]){
				tree++;
				if(x != root || tree >= 2){
					is[x] = true;
				}
			}
		}
		else{
			low[x] = min(low[x], dfn[o]);
		}
	}
}

Tarjan(割边)


int n, m;
struct node{
	int u, v;
};
vector<node>e;
vector<int > h[N];
inline void add(int from, int to){
	e.push_back({from, to});
	h[from].push_back(e.size() - 1);
}
vector<node>ans;
int tot, dfn[N], low[N];
inline void tarjan(int x, int ith){
	dfn[x] = low[x] = ++tot;
	for(int i = 0; i < h[x].size(); ++i){
		int tt = h[x][i], j = e[tt].v;
		if(!dfn[j]){
			tarjan(j, tt);
			low[x] = min(low[x], low[j]);
			if(low[j] > dfn[x]){
				ans.push_back({x, j});
			}
		}
		else{
			if(tt != (1 ^ ith)){
				low[x] = min(low[x], dfn[j]);
			}
		}
	}
}

倍增求LCA


int fa[N][30], dep[N], m, n, s;
vector<int> e[N];
inline void pre(int now, int father){
	fa[now][0] = father;
	dep[now] = dep[father] + 1;
	for(int i = 1; i <= 23; ++i){
		fa[now][i] = fa[fa[now][i - 1]][i - 1];
	}
	for(const auto o : e[now]){
		if(o != father){
			pre(o, now);
		}
		continue;
	}
}
inline int get(int u, int v){
	if(u == v){
		return v;
	}
	if(dep[v] > dep[u]){
		swap(u, v);
	}
	for(int i = 23; i >= 0; --i){
		if(dep[fa[u][i]] >= dep[v]){
			u = fa[u][i];
		}
	}
	if(u == v){
		return v;
	}
	for(int i = 23; i >= 0; --i){
		if(fa[u][i] != fa[v][i]){
			u = fa[u][i], v = fa[v][i];
		}
	}
	return fa[u][0];
}

Tarjan求LCA(利用并查集)


离线算法 需等所有查询输入完后给出答案

int fa[N], vis[N], m, n, s;
vector<int> e[N];
inline int getf(int x){ return fa[x] == x ? x : fa[x] = getf(fa[x]); };
vector<pair<int, int>> query[N];
int ans[N];
inline void tarjan(int x){
	vis[x] = 1;
	for(const auto o : e[x]){
		if(!vis[o]){
			// vis[o] = 1;
			tarjan(o);
			fa[o] = x;
		}
	}
	for(const auto ask : query[x]){
		if(vis[ask.first]){
			ans[ask.second] = getf(ask.first);
		}
	}
}
main(){
	n = read(), m = read(), s = read();
	for(int i = 1; i <= (n - 1); ++i){
		int aa = read(), bb = read();
		e[bb].push_back(aa);
		e[aa].push_back(bb);
	}
	for(int i = 1; i <= m; ++i){
		int aa = read(), bb = read();
		query[aa].push_back({bb, i});
		query[bb].push_back({aa, i});
	}
	//调用即可
}

数据结构相关


并查集


inline int getf(int x){return fa[x] == x ? x : fa[x] == getf(fa[x]);}

剩下的晚上回家写写吧 明天rp++

posted @ 2026-09-03 16:27  fl0ppy-  阅读(6)  评论(0)    收藏  举报