/*
created by scarlyw
基础图论模板
*/
#include <bits/stdc++.h>
//三种图论最短路
namespace shortest_path_faster_algorithm {
//Floyed算法 O(n ^ 3)
const int MAXN = 100 + 10;
int n, m, x, y, z;
int map[MAXN][MAXN];
inline void floyed() {
std::cin >> n >> m, memset(map, 50, sizeof(map));
for (int i = 1; i <= m; ++i) {
std::cin >> x >> y >> z;
map[x][y] = std::min(map[x][y], z);
map[y][x] = std::min(map[y][x], z);
}
for (int i = 1; i <= n; ++i) map[i][i] = 0;
for (int k = 1; k <= n; ++k)
for (int i = 1; i <= n; ++i)
for (int j = 1; j <= n; ++j)
map[i][j] = std::min(map[i][j], map[i][k] + map[k][j]);
}
//dijkstra算法 O(nlogn)
namespace solve_dijkstra {
const int MAXN = 10000 + 10;
struct node {
int to, w;
node(int to = 0, int w = 0) : to(to), w(w) {}
inline bool operator < (const node &a) const {
return w > a.w;
}
} ;
std::vector<node> edge[MAXN];
inline void add_edge(int x, int y, int z) {
edge[x].push_back(node(y, z)), edge[y].push_back(node(x, z));
}
int n, m, s, x, y, z;
inline void read_in() {
std::cin >> n >> m >> s;
for (int i = 1; i <= m; ++i) std::cin >> x >> y >> z, add_edge(x, y, z);
}
//优先队列实现
inline void dijkstra(int s, int t) {
std::priority_queue<node> q;
static int dis[MAXN];
static bool vis[MAXN];
memset(dis, 127, sizeof(int) * (n + 1));
memset(vis, false, sizeof(bool) * (n + 1));
dis[s] = 0, q.push(node(s, 0));
while (!q.empty()) {
while (!q.empty() && vis[q.top().to]) q.pop();
if (q.empty()) break ;
int cur = q.top().to;
vis[cur] = true, q.pop();
for (int p = 0; p < edge[cur].size(); ++p) {
node *e = &edge[cur][p];
if (!vis[e->to] && dis[e->to] > dis[cur] + e->w)
dis[e->to] = dis[cur] + e->w, q.push(node(e->to, dis[e->to]));
}
}
std::cout << dis[t];
}
}
//spfa算法 O(nm)
namespace solve_spfa {
const int MAXN = 10000 + 10;
struct node {
int to, w;
node(int to = 0, int w = 0) : to(to), w(w) {}
} ;
std::vector<node> edge[MAXN];
inline void add_edge(int x, int y, int z) {
edge[x].push_back(node(y, z)), edge[y].push_back(node(x, z));
}
int n, m, s, x, y, z;
inline void read_in() {
std::cin >> n >> m >> s;
for (int i = 1; i <= m; ++i) std::cin >> x >> y >> z, add_edge(x, y, z);
}
inline void spfa(int s, int t) {
std::queue<int> q;
static int dis[MAXN];
static bool vis[MAXN];
memset(dis, 127, sizeof(int) * (n + 1));
memset(vis, false, sizeof(bool) * (n + 1));
dis[s] = 0, q.push(s);
while (!q.empty()) {
int cur = q.front();
q.pop(), vis[cur] = false;
for (int p = 0; p < edge[cur].size(); ++p) {
node *e = &edge[cur][p];
if (dis[e->to] > dis[cur] + e->w) {
dis[e->to] = dis[cur] + e->w;
if (!vis[e->to]) q.push(e->to), vis[e->to] = true;
}
}
}
std::cout << dis[t];
}
}
}
//floyed 求最小环 O(n ^ 3)
namespace floyed_cycle {
const int MAXN = 100 + 10;
int n, m, x, y, z;
int map[MAXN][MAXN], g[MAXN][MAXN];
inline void read_in() {
std::cin >> n >> m, memset(map, 35, sizeof(map));
for (int i = 1; i <= m; ++i) {
std::cin >> x >> y >> z;
map[x][y] = std::min(map[x][y], z), map[y][x] = std::min(map[y][x], z);
}
for (int i = 1; i <= n; ++i) map[i][i] = 0;
memcpy(g, map, sizeof(g));
}
inline void floyed() {
int ans = ~0u >> 1;
for (int k = 1; k <= n; ++k) {
for (int i = 1; i < k; ++i)
for (int j = 1; j < i; ++j)
ans = std::min(ans, map[i][k] + map[k][j] + g[i][j]);
for (int i = 1; i <= n; ++i)
for (int j = 1; j <= n; ++j)
g[i][j] = std::min(g[i][k] + g[k][j], g[i][j]);
}
if (ans == (~0u >> 1)) std::cout << "No solution.";
else std::cout << ans;
}
}
//最小生成树
namespace minimal_spanning_tree {
//prim算法 O(n ^ 2)
namespace prim {
const int MAXN = 1000 + 10;
int n, mst;
int map[MAXN][MAXN], min_cost[MAXN];
std::cin >> n;
for (int i = 1; i <= n; ++i)
for (int j = 1; j <= n; ++j)
std::cin >> map[i][j];
for (int i = 1; i <= n; ++i) min_cost[i] = map[1][i];
min_cost[1] = -1;
for (int i = 1; i < n; ++i) {
int pos = -1;
for (int j = 1; j <= n; ++j)
if (min_cost[j] != -1 && (pos == -1 || min_cost[j] < min_cost[pos]))
pos = j;
mst += min_cost[pos], min_cost[pos] = -1;
for (int j = 1; j <= n; ++j)
min_cost[j] = std::min(min_cost[j], map[pos][j]);
}
std::cout << mst;
}
//kruscal O(m log m)
namespace kruscal {
const int MAXN = 100000 + 10;
int ans, mst, n, m;
int father[MAXN];
struct edges {
int x, y, w;
inline bool operator < (const edges &a) const {
return w < a.w;
}
} e[MAXN];
inline int get_father(int x) {
return (father[x] == x) ? (x) : (father[x] = get_father(father[x]));
}
inline void solve() {
std::cin >> n >> m;
for (int i = 1; i <= n; ++i) father[i] = i;
for (int i = 1; i <= m; ++i)
std::cin >> e[i].x >> e[i].y >> e[i].w;
std::sort(e + 1, e + m + 1);
for (int i = 1; i <= m; ++i) {
int x = e[i].x, y = e[i].y, fa1 = get_father(x), fa2 = get_father(y);
if (fa1 != fa2) father[fa1] = fa2, mst += e[i].w;
}
std::cout << mst;
}
}
}
//tarjan O(n)
namespace tarjan {
inline void tarjan(int cur) {
num[cur] = low[cur] = ++ind, vis[cur] = true, s.push_back(cur);
for (int p = 0; p < edge[cur].size(); ++p) {
int v = edge[cur][p];
if (num[v] == 0) tarjan(v), low[cur] = std::min(low[cur], low[v]);
else if (vis[v]) low[cur] = std::min(low[cur], num[v]);
}
if (low[cur] == num[cur]) {
++top;
do {
o = s.back(), vis[o] = false, scc[o] = top, s.pop_back();
} while (o != cur);
}
}
}
//拓扑排序
namespace top_sort {
//top里面存储排好序的点
std::vector<int> top;
inline void dfs(int cur) {
vis[cur] = true;
for (int p = 0; p < edge[cur].size(); ++p) {
int v = edge[cur][p];
dfs(v);
}
top.push_back(v);
}
}
NOIP前 基础图论模板
最新推荐文章于 2020-05-04 17:05:43 发布