图论基础算法模板

本文介绍了图论中的基础算法,包括Dijkstra算法的邻接表、邻接矩阵及堆优化实现,用于求解单源最短路径问题。此外,还提到了SPFA算法和在LeetCode上的应用题目。同时,讨论了最小生成树的Prime算法和Kruskal算法模板,是学习图论和数据结构的重要参考资料。
摘要由CSDN通过智能技术生成

最短路

Dijkstra算法(邻接表)
可以有重边,自环,边权为正数

洛谷P3371 【模板】单源最短路径(弱化版)

#include<iostream>
#include<cstring>
#include<cstdio>
#include<vector>
#include<algorithm>
#include<climits>
using namespace std;
const int maxn=500050;
const int inf=0x3f3f3f3f;

struct edge{
   
    int to,weight;
};

vector<edge>e[maxn];
int n,m,s;
int dis[maxn],vis[maxn];
void dijkstra(int s){
   
    fill(dis,dis+1+n,inf);
    fill(vis,vis+1+n,0);
    dis[s]=0;
    int turn = n;
    for(int i=1;i<=n;i++){
   
        int target=-1;
        for(int j=1;j<=n;j++){
   
            if(!vis[j]&&(target==-1||dis[target]>dis[j]))
    			target=j;
    	}
    	if(target==-1)
    		break;
        vis[target]=1;
        for(int j=0;j<e[target].size();j++){
   
            if(dis[target]!=inf)
                dis[e[target][j].to]=min(dis[e[target][j].to],dis[target]+e[target][j].weight);
    	}
    }
}

 
int main() {
   
	cin>>n>>m>>s;
	for(int i=1;i<=m;i++){
   
		int x,y,z;
		cin>>x>>y>>z; 
		e[x].push_back({
   y,z});
		//e[y].push_back({x,z});
	}
    dijkstra(s);
    for(int i=1;i<=n;i++){
   
    	if(dis[i]==inf) cout<<(1<<31)-1<<" ";
    	else cout<<dis[i]<<" ";
	} 
    return 0;
}

Dijkstra算法(邻接矩阵)
可以有重边,自环,边权为正数

洛谷P3371 【模板】单源最短路径(弱化版)

#include<iostream>
#include<cstring>
#include<cstdio>
#include<vector>
#include<algorithm>
#include<climits>
using namespace std;
const int maxn=10005;
const int inf=0x3f3f3f3f;
int graph[maxn][maxn];
int n,m,s;
int dis[maxn],vis[maxn];


void dijkstra(int s){
   
    fill(dis,dis+1+n,inf);
    fill(vis,vis+1+n,0);
    dis[s]=0;
    for(int i=1;i<=n;i++){
   
        int target=-1;
        for(int j=1;j<=n;j++){
   
            if(!vis[j]&&(target==-1||dis[target]>dis[j]))
    			target=j;
    	}
    	if(target==-1)
    		break;
        vis[target]=1;
        for(int j=1;j<=n;j++){
   
            if(dis[target]!=inf)
            	dis[j]=min(dis[j],dis[target]+graph[target][j]);
    	}
    }
}

 
int main() {
   
	cin>>n>>m>>s;
	fill(graph[0],graph[0]+maxn*maxn,inf);
	for(int i=1;i<=m;i++){
   
		int x,y,z;
		cin>>x>>y>>z;
		graph[x][y]=min(graph[x][y],z);
	}
    dijkstra(s);
 	for(int i=1;i<=n;i++){
   
    	if(dis[i]==inf) cout<<(1<<31)-1<<" ";
    	else cout<<dis[i]<<" ";
	} 
    return 0;
}

Dijkstra是基于一种贪心的策略,首先用数组dis记录起点到每个结点的最短路径,再用一个数组保存已经找到最短路径的点然后,从dis数组选择最小值,则该值就是源点s到该值对应的顶点的最短路径,并且把该点记为已经找到最短路,此时完成一个顶点,再看这个点能否到达其它点(记为v),将dis[v]的值进行更新,不断重复上述动作,将所有的点都更新到最短路径。

Dijkstra算法(堆优化)
使用优先队列实现:

洛谷P3371 【模板】单源最短路径(弱化版)

#include<iostream>
#include<queue>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值