图论问题总述

最短路

1.Dijkstra

Dijkstra用于计算一个顶点到其他所有顶点的最短路径。Dijkstra 算
法的主要特点是以起点为中心,逐层向外扩展一个点,每次都会取一个最近点继续扩展,直到取完所有点为止。但Dijkstra 算法要求图中不能出现负权边。

//模板
#include<bits/stdc++.h>
using namespace std;


int n,m;

struct node{
	int v,w;
	node(){ };
	node(int _v,int _w){
		v=_v;
		w=_w;
	}
};

vector <node> g[10100];

bool vis[10100];
int dst[10100];

void add(int u,int v,int w){
	g[u].push_back(node(v,w));
	g[v].push_back(node(u,w));
}


void dij(int s){
	memset(dst,0x3f,sizeof dst);
	
	int u = s;
	dst[u]=0;
	vis[u]=1;
	
	int nn=n;
	while(nn--){
		for(int j=0;j<g[u].size();j++){
			
			int v = g[u][j].v;
			int w = g[u][j].w;
			dst[v] = min(dst[v],dst[u]+w);
			
		}
		
		int mi=0x3f3f3f3f;
		for(int j=1;j<=n;j++){
			if(!vis[j]&&mi>dst[j]){
				mi = dst[j];
				u = j;	
			}
		}
		vis[u] = 1;	
	}
}


int main(){
	cin >> n >>m;
	int u,v,w;
	while (m--){
		cin >> u >> v >> w;
		add(u,v,w);
	}
	
	dij(1);
	cout << dst[n];
	
	return 0;
}
2.SPFA

SPFA算法是单源最短路径的一种算法,通常被认为是 Bellmanford算法的队列优化,在代码形式上接近宽度优先搜索 BFS,是一个在实践中非常高效的单源最短路算法。它会在每次更新了最短路以后又重新入队从而去更新后续结点的最短路。同时有些题有卡SPFA的数据,所以也可以换成Dijkstra。但Dijkstra 不能处理有负权的图,而 SPFA 可以处理不含负环的图的最短路,并能 判断是否存在负环。

//模板
#include<bits/stdc++.h>
using namespace std;

const int maxn=1010;
const int inf=0x3f3f3f3f;

int n,m;

struct node{
	int v,w;
	node(){ }
	node(int _v,int _w){
		v=_v;
		w=_w;
	}
};

vector <node> g[maxn];
int dst[maxn];
queue <int> qu;
int inq[maxn];

int add(int u,int v,int w){
	g[u].push_back(node(v,w));
	g[v].push_back(node(u,w));
}

void spfa(int s){
	memset(dst,inf,sizeof dst);
	int u=s;
	dst[u]=0;
	qu.push(u);
	inq[u]=1;
	while(!qu.empty()){
		u=qu.front();
		qu.pop();
		inq[u]=0;
		for(int i=0;i<g[u].size();i++){
			int v=g[u][i].v;
			int w=g[u][i].w;
			if(dst[v]>dst[u]+w){
				dst[v]=dst[u]+w;
				if(!inq[v]){
					qu.push(v);
					inq[v]=1;
				}
			}
		}
	}
}


int main(){
	cin >> n >> m;
	int u , v , w; 
	while (m--){
		cin >> u >> v >> w;
		add(u,v,w);
	}
	spfa(1);
	cout << dst[n]<<endl;
	return 0;
}
Floyd

个人认为Floyd较Dijkstra和SPFA更难理解,所以就不写太多,但代码很短。

#include<bits/stdc++.h>
using namespace std;
const int N = 1e2 + 9;
const int inf = 0x3f3f3f3f;
int mp[N][N];
void floyd(int n) {
	for (int k = 1; k <= n; ++k) {
		for (int i = 1; i <= n; ++i) {
			for (int j = 1; j <= n; ++
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值