模版(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
若 i 到 j 之间有边,则 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++
浙公网安备 33010602011771号