好久不碰OI了,最近决定把各种基础算法的模板和用法整理下。
·SPFA
-求瓶颈路 洛谷 1396
-求最短路 好多。。
-路上最值 洛谷 1073
-边的特殊处理 eg. 加入点出点 暑末Day2 T1
-判负环 可结合分数规划食用
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1010;
const int inf = 0x3f3f3f3f;
struct node{
int v, w, nxt;
} edge[maxn*maxn*2];
int dis[maxn], vis[maxn], st[maxn];
int n, m, tot;
queue<int> q;
inline void in(int x, int y, int z){
edge[++tot].v = y;
edge[tot].w = z;
edge[tot].nxt = st[x];
st[x] = tot;
}
inline void SPFA(){
for(int i = 0; i <= n; i++)
dis[i] = inf;
vis[1] = 1;
dis[1] = 0;
q.push(1);
while(!q.empty()){
int now = q.front(); q.pop();
vis[now] = 0;
for(int i = st[now]; i; i = edge[i].nxt){
int to = edge[i].v;
if(!vis[to] && dis[to] > dis[now] + edge[i].w){
dis[to] = dis[now] + edge[i].w;
vis[to] = 1;
q.push(to);
}
}
}
printf("%d\n", dis[n]);
}
int main(){
scanf("%d%d", &n, &m);
for(int i = 1, x, y, z; i <= m; i++){
scanf("%d%d%d", &x, &y, &z);
in(x, y, z);
}
SPFA();
return 0;
}
·Dijkstra
-稠密图最短路!
-有关贪心的图论 洛谷 1875
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1010;
const int inf = 0x3f3f3f3f;
struct data{
int v, w, nxt;
} edge[maxn*maxn*2];
struct node{
int point, w;
bool operator < (const node& a) const {
return w < a.w;
}
};
int dis[maxn], vis[maxn], st[maxn];
int n, m, tot;
queue<int> q;
inline void in(int x, int y, int z){
edge[++tot].v = y;
edge[tot].w = z;
edge[tot].nxt = st[x];
st[x] = tot;
}
inline void Dijkstra(){
priority_queue<node> q;
for(int i = 0; i <= n; i++) dis[i] = inf;
q.push((node){1, 0});
dis[1] = 0;
while(!q.empty()){
node now = q.top(); q.pop();
if(vis[now.point]) continue;
vis[now.point] = 1;
for(int i = st[now.point]; i; i = edge[i].nxt){
int to = edge[i].v;
if(dis[to] > dis[now.point] + edge[i].w){
dis[to] = dis[now.point] + edge[i].w;
q.push((node){to, dis[to]});
}
}
}
printf("%d\n", dis[n]);
}
int main(){
scanf("%d%d", &n, &m);
for(int i = 1, x, y, z; i <= m; i++){
scanf("%d%d%d", &x, &y, &z);
in(x, y, z);
}
Dijkstra();
return 0;
}
·Kruskal
-瓶颈生成树 货车运输
#include<bits/stdc++.h>
using namespace std;
const int maxn = 5050;
const int maxm = 200020;
struct node{
int x, y, w;
//bool operator < (const node &p) const{ return w < p.w; }
} a[maxm];
int n, m, fa[maxn];
inline void getInit(){
for(int i = 0; i <= n; i++) fa[i] = i;
}
inline int find(int x){
if(x == fa[x]) return x;
return fa[x] = find(fa[x]);
}
inline void merge(int x, int y){
fa[find(x)] = find(y);
}
inline bool cmp(node p, node q){
return p.w < q.w;
}
inline void Kruskal(){
int sum = 0, tot = 0;
getInit();
sort(a+1, a+m+1, cmp);
for(int i = 1; i <= m; i++){
int fx = find(a[i].x);
int fy = find(a[i].y);
if(fx != fy){
merge(fx, fy);
sum += a[i].w;
tot++;
}
//else break;
}
if(tot >= n-1) printf("%d\n", sum);
else printf("orz\n");
}
int main(){
scanf("%d%d", &n, &m);
for(int i = 1; i <= m; i++)
scanf("%d%d%d", &a[i].x, &a[i].y, &a[i].w);
Kruskal();
return 0;
}
·Tarjan
-求强联通分量
-缩点
#include<cstdio>
#include<iostream>
using namespace std;
const int maxn = 200050;
struct node{
int v, nxt;
} edge[maxn];
int stack[maxn], dfn[maxn], low[maxn], sum[maxn], belong[maxn], st[maxn];
int n, m, a, b, t, tot, top, index, bcnt;
bool instack[maxn];
inline void in(int x, int y){
edge[++tot].v = y;
edge[tot].nxt = st[x];
st[x] = tot;
}
inline void Tarjan(int u){
stack[top++] = u;
instack[u] = 1;
dfn[u] = low[u] = ++index;
for(int i = st[u]; i; i = edge[i].nxt){
int to = edge[i].v;
if(!dfn[to]){
Tarjan(to);
low[u] = min(low[u], low[to]);
}
else if(instack[to])
low[u] = min(dfn[to], low[u]);
}
if(dfn[u] == low[u]){
bcnt++;
int to;
do{
to = stack[--top];
sum[bcnt]++;
belong[to] = bcnt;
instack[to] = 0;
} while(u != to);
}
}
int main(){
scanf("%d", &n);
for(int i = 1; i <= n; i++){
scanf("%d", &b);
in(i, b);
}
for(int i = 1; i <= n; i++)
if(!dfn[i]) Tarjan(i);
}
·拓扑排序
-删边找环
#include<bits/stdc++.h>
using namespace std;
const int maxn = 200005;
int n, tot;
int st[maxn], vis[maxn], rd[maxn];
queue<int> q;
struct node{
int v, nxt;
} edge[maxn*2];
inline void in(int x, int y){
edge[++tot].v = y;
edge[tot].nxt = st[x];
st[x] = tot;
}
inline void Topsort(){
for(int i = 1; i <= n; i++)
if(!rd[i]){
vis[i] = 1;
q.push(i);
}
while(!q.empty()){
int now = q.front(); q.pop();
for(int i = st[now]; i; i = edge[i].nxt){
int to = edge[i].v;
if(rd[to] == 1){
rd[to]--;
vis[to] = 1;
q.push(to);
}
}
}
}
int main(){
scanf("%d", &n);
for(int i = 1, y; i <= n; i++){
scanf("%d", &y);
in(i, y);
rd[y]++;
}
Topsort();
}