图论基础#
图的存储#
邻接表存图#
对于每一个节点,记录这个几点连接的所有其他节点和对应权值
1#include <bits/stdc++.h>
2using namespace std;
3const int N = 100010;
4vector<pair<ll,int> graph[N];//图,{权值,对应的节点}
5int n,m;
6int main(){
7 cin>>n>>m;
8 for(int i = 0;i<m;i++){
9 int u,v,w;
10 cin>>u>>v>>w;
11 graph[u].push_back({w,v});
12 graph[v].push_back({w,u});
13 }
14}邻接矩阵存图#
用一个二维数组记录每两个点之间的距离
两个索引分别代表两个点 g[i][j]的值代表点i和j之间的距离
1#define ll long long
2const int N = 200010;
3const ll INF = 4e18;
4ll g[N][N];
5int main(){
6 int n,m;
7 cin>>n>>m;
8 for(int i = 1;i<=n;i++){
9 for(int j = 1;j<=n;j++){
10 if(i==j){
11 g[i][j] = 0;//同一个点当然是0
12 }else{
13 g[i][j] = INF;//初始化矩阵为INF(不可达)
14 }
15 }
16 }
17 for(int i = 0;i<m;i++){
18 int u,v;
19 ll w;
20 cin>>u>>v>>w;
21 //无向图
22 g[u][v] = min(g[u][v],w);
23 g[v][u] = min(g[v][u],w);//注意 这里出现重边时取用min是绝大部分情况 不排除其他写法
24 //如果是有向图,只用下面这一行
25 //g[u][v] = min(g[u][v],w);
26 }
27}稠密图&稀疏图#
令n=点数 m=边数
因此无向图最大边数=(n*(n-1))/2
如果m接近于这个最大边数 就是稠密图
如果m接近n或者更小 就是稀疏图
可以根据稀疏和稠密的性质选择算法 获得更高效率
最小生成树#
复杂度
Prim–>O(n^2)
Prim堆优化–>O(m log n)
Kruskal–>O(m log m)
一般来说
稠密图->朴素Prim
稀疏图->Kruskal或者堆优化Prim
另外:
- 如果n与m很接近(n==m)
选择Kruskal和堆优化Prim在复杂度上没有差异
但是Kruskal是基于sort排序和并查集 更快且不容易写错
选择Kruskal
