图论
图和最短路
图的深搜
邻接矩阵与邻接表的优缺点对比
空间方面:当图的顶点数很多、但是边的数量很少时,如果用邻接矩阵,我们就需要开一个很大的二维数组,最后我们需要存储 n*n 个数。但是用邻接表,最后我们存储的数据量只是边数的两倍。
效率方面:用邻接表存图的最大缺点就是随机访问效率低。比如,我们需要询问点 a 是否和点 b 连,我们就要遍历
邻接表可以记录重复边:如果两个点之间有多条边,用邻接矩阵只能记录一条,但是用邻接表就能记录多条。虽然重复的边看起来是多余的,但在很多时候对解题来说是必要的。
因此,我们需要对不同的应用情景选择不同的存图方法。
如果是稀疏图(顶点很多、边很少),一般用邻接表;
如果是稠密图(顶点很少、边很多),一般用邻接矩阵。
void add(int a,int b){
//a->b
e[idx] = b,ne[idx] = h[a],h[a] = idx ++;//邻接表,g[a][b]是邻接矩阵,只有稠密图才不浪费
}
bool st[N];
//图的深搜
// void dfs(int u){
// st[u] = true;
// for(int i = h[u];i != -1;i = ne[i]){
// int j = e[i];
// if(!st[j]){
// dfs(j);
// }
// }
// }
//
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define endl '\n'
#define ios ios::sync_with_stdio(false);cin.tie(0);
#define x first
#define y second//pair
#define pb push_back
#define fix(n) fixed << setprecision(n)
#define INF 0x7fffffff
#define debug(a) cout<<"======"<<a<<"======"<<endl;
#define int long long
typedef pair<int,int> pii;
inline int gcd(int a,int b){return b ? gcd(b, a % b) : a;}
inline int lcm(int a,int b){return a/gcd(a,b)*b;}
const int N = 1e5 + 10;
int dx[4] = {-1,0,1,0};
int dy[4] = {0,1,0,-1};
int n, m, k, t;
int h[N],e[2*N],ne[2*N];
int idx;
void add(int a,int b){
//a->b
e[idx] = b,ne[idx] = h[a],h[a] = idx ++;
}
bool st[N];
//图的深搜 根据题目修改版
int ans = INF;
int dfs(int u){
st[u] = true;
int sum = 1,res = 0;//sum是子树的点的个数,当前算个点,从1开始
for(int i = h[u];i != -1;i = ne[i]){
int j = e[i];
if(!st[j]){
int s = dfs(j);
res = max(res,s);
sum += s;
}
}
res = max(res,n - sum);
ans = min(res,ans);
return sum;
}
void work(){
idx = 0;
memset(h,-1,sizeof h);
cin >> n;
for(int i = 0;i < n - 1;i ++){
int a,b;
cin >> a >> b;
add(a,b),add(b,a);//无向边
}
dfs(1);
cout << ans << endl;
}
signed main(){
int T = 1;
//cin >> T;
while(T --){
work();
}
return 0;
}
Dijkstra
朴素
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define endl '\n'
#define ios ios::sync_with_stdio(false);cin.tie(0);
#define x first
#define y second//pair
#define pb push_back
#define fix(n) fixed << setprecision(n)
#define INF 0x3f3f3f3f
#define debug(a) cout<<"======"<<a<<"======"<<endl;
//#define int long long//在这题出了问题,如果不注释掉
typedef pair<int,int> pii;
inline int gcd(int a,int b){return b ? gcd(b, a % b) : a;}
inline int lcm(int a,int b){return a/gcd(a,b)*b;}
const int N = 510;
int dx[4] = {-1,0,1,0};
int dy[4] = {0,1,0,-1};
int n, m, k;
int h[N],e[2*N],ne[2*N];
int idx;
int g[N][N];
int d[N];
bool st[N];//该点最短路是否确定
// void add(int a,int b){
// //a->b
// e[idx] = b,ne[idx] = h[a],h[a] = idx ++;
// }
int dijkstra(){
memset(d,0x3f3f3f3f,sizeof d);
d[1] = 0;
for(int i = 0;i < n;i ++){
int t = -1;
for(int j = 1;j <= n;j ++){
if(!st[j] &&(t == -1 || d[t]>d[j])){
t = j;
}
}
st[t] = true;
for(int j = 1;j <= n;j ++) d[j] = min(d[j],d[t] + g[t][j]);
}
if(d[n] == INF)return -1;
else return d[n];
}
void work(){
memset(g,0x3f3f3f3f,sizeof g);
cin >> n >> m;
while(m --){
int a,b,c;
cin >> a >> b >> c;
g[a][b] = min(g[a][b],c);//除去自环和重叠的;
}
int t = dijkstra();
cout << t << endl;
}
signed main(){
int T = 1;
//cin >> T;
while(T --){
work();
}
return 0;
}
#include<iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 510, M = 100010;
int h[N], e[M], ne[M], w[M], idx;//邻接表存储图
int state[N];//state 记录是否找到了源点到该节点的最短距离
int dist[N];//dist 数组保存源点到其余各个节点的距离
int n, m;//图的节点个数和边数
void add(int a, int b, int c)//插入边
{
e[idx] = b, w[idx] = c, ne[idx] = h[a], h[a] = idx++;
}
void Dijkstra()
{
memset(dist, 0x3f, sizeof(dist));//dist 数组的各个元素为无穷大
dist[1] = 0;//源点到源点的距离为置为 0
for (int i = 0; i < n; i++)
{
int t = -1;
for (int j = 1; j <= n; j++)//遍历 dist 数组,找到没有确定最短路径的节点中距离源点最近的点t
{
if (!state[j] && (t == -1 || dist[j] < dist[t]))
t = j;
}
state[t] = 1;//state[i] 置为 1。
for (int j = h[t]; j != -1; j = ne[j])//遍历 t 所有可以到达的节点 i
{
int i = e[j];
dist[i] = min(dist[i], dist[t] + w[j]);//更新 dist[j]
}
}
}
int main()
{
memset(h, -1, sizeof(h));//邻接表初始化
cin >> n >> m;
while (m--)//读入 m 条边
{
int a, b, w;
cin >> a >> b >> w;
add(a, b, w);
}
Dijkstra();
if (dist[n] != 0x3f3f3f3f)//如果dist[n]被更新了,则存在路径
cout << dist[n];
else
cout << "-1";
return 0;
}
本文作者:Go1NgZCY
本文链接:https://www.cnblogs.com/going-zcy/p/18062146
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步