最短路总结

// Floyd多源最短路算法 O(n^3)

#include <iostream>

#include <cmath>

#include <cstring>

#include<algorithm>

using namespace std;

const int N = 101;

int g[N][N];

void Floyd(int n) {

for(int i=1; i<=n; i++){

for(int j=1; j<=n; j++){

for(int k=1; k<=n; k++){

g[j][k]=min(g[j][k],g[j][i]+g[i][k]);

}

}

}

}

int main() {

memset(g, 0x3f, sizeof(g));

for (int i = 0; i < N; i++) {

g[i][i] = 0;

}

int n, m;

int u, v, w;

cin >> n >> m;

for (int i = 0; i < m; i++) {

cin >> u >> v >> w;

g[u][v] = g[v][u] = w;

}

Floyd(n);

for (int i = 1; i <= n; i++) {

for (int j = 1; j <= n; j++) {

cout << g[i][j] << " ";

}

cout << endl;

}

return 0;

}

//朴素的Dijkstra算法(单源最短路 正环)O(n^2)适用于稠密图

#include<iostream>

#include<algorithm>

#include<cstdio>

#include<cstring>

#include<cmath>

#include<vector>

#include<queue>

#include<set>

using namespace std;

const int inf=0x7fffffff;

bool vis[1005];

int d[1005];

struct node{

int v,w;

node(){

}

node(int v2,int w2){

v=v2;

w=w2;

}

};

vector<node> g[1005];

int n,m,s;

int main(){

cin>>n>>m>>s;

for(int i=1; i<=n; i++){

int u,v,w;

cin>>u>>v>>w;

g[u].push_back(node(v,w));

g[v].push_back(node(u,w));

}

memset(d,0x3f,sizeof(d));

d[s]=0;

for(int i=1; i<=n; i++){

int minn=inf;int v=0;

for(int j=1; j<=n; j++){

if(!vis[i]&&d[j]<minn)

{

minn=d[j];

v=j;

}

}

if(minn==inf){

break;

}

vis[v]=true;

for(int j=0; j<g[v].size(); j++){

d[g[v][j].v]=min(d[g[v][j].v],g[v][j].w+d[v]);

}

}

for(int i=1; i<=n; i++){

cout<<d[i]<<" ";

}

return 0;

}

//堆优化的Dijkstra算法(单源最短路 正环)O(m logn)适用于稀疏图

#include<iostream>

#include<algorithm>

#include<cstdio>

#include<cstring>

#include<cmath>

#include<vector>

#include<queue>

#include<set>

using namespace std;

struct node{

int v,w;

node(){

}

node(int v2,int w2){

v=v2;

w=w2;

}

};

set <pair<int,int>> minn;

vector <node> g[1005];

int d[1005];

int main(){

int n,m,s;

cin>>n>>m>>s;

for(int i=1; i<=n; i++){

int u,v,w;

cin>>u>>v>>w;

g[u].push_back(node(v,w));

g[v].push_back(node(u,w));

}

memset(d,0x3f,sizeof(d));

d[s]=0;

minn.insert(make_pair(0,s));

while(minn.size()){

int mind=minn.begin()->first;

int v=minn.begin()->second;

minn.erase(minn.begin());

for(int i=0; i<g[v].size(); i++){

if(d[g[v][i].v]>g[v][i].w+d[v]){

minn.erase(make_pair(d[g[v][i].v],g[v][i].v));

d[g[v][i].v]=d[v]+g[v][i].w;

minn.insert(make_pair(d[g[v][i].v],g[v][i].v));

}

}

}

for(int i=1; i<=n; i++){

cout<<d[i]<<" ";

}

return 0;

}

//SPFA算法(多源最短路 正负环)一般O(m),最坏O(nm)

#include<iostream>

#include<algorithm>

#include<cstdio>

#include<cstring>

#include<cmath>

#include<vector>

#include<queue>

#include<set>

using namespace std;

struct node{

int v,w;

node(){

}

node(int vv,int ww){

w=ww;

v=vv;

}

};

vector <node>g[1005];

bool f[1005];

queue<int > q;

int d[1005];

signed main(){

int n,m,s;

cin>>n>>m>>s;

for(int i=1; i<=n ; i++){

int u,v,w;

cin>>u>>v>>w;

g[u].push_back(node(v,w));

g[v].push_back(node(u,w));

}

memset(d,0x3f,sizeof(d));

d[s]=0;

f[s]=1;

q.push(s);

while(!q.empty()){

int now=q.front();

f[now]=0;

q.pop();

for(int i=0; i<g[now].size(); i++){

int x=g[now][i].v;

if(d[x]>d[now]+g[now][i].w){

d[x]=d[now]+g[now][i].w;

if(!f[x]){

f[x]=1;

q.push(x);

}

}

}

}

for(int i=1; i<=n; i++){

cout<<d[i]<<" ";

}

return 0;

}

//SPFA判断负环

#include<iostream>

#include<algorithm>

#include<cstdio>

#include<cstring>

#include<cmath>

#include<vector>

#include<queue>

#include<set>

using namespace std;

struct node{

int v,w;

node(){

}

node(int vv,int ww){

v=vv;

w=ww;

}

};

queue<int> q;

int d[1005],cnt[1005];

vector<node> g[1005];

bool f[1005];

int main(){

int n,m,s,u,v,w;

cin>>n>>m>>s;

for(int i=1; i<=n; i++){

cin>>u>>v>>w;

g[u].push_back(node(v,w));

g[v].push_back(node(u,w));

}

memset(d,0,sizeof(d));

d[s]=0;

f[s]=1;

q.push(s);

cnt[s]++;

while(!q.empty()){

int now=q.front();

q.pop();

f[now]=0;

if(cnt[now]>n){

cout<<"YES";

return 0;

}

for(int i=0; i<g[now].size(); i++){

int x=g[now][i].v;

if(d[x]>d[now]+g[now][i].w){

d[x]=d[now]+g[now][i].w;

if(!f[x]){

q.push(x);

cnt[x]++;

f[x]=1;

}

}

}

}

cout<<"NO";

return 0;

}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值