NOIP前 基础图论模板

/*
	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);
}
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值