最短路模板

Dijkstra

#include <iostream>
#include <stdio.h>
#include <string>
#include <string.h>
#include <queue>
#include <vector>
#define INF 0x3f3f3f3f

using namespace std;
const int maxn = 105;
int dis[maxn], pre[maxn];

struct Edge//边 
{
    int u, v, w;
    Edge() {};
    Edge(int uu, int vv, int ww): u(uu), v(vv), w(ww) {};
};

vector<Edge> edges;//边数组 
vector<int> G[maxn];//存储每个节点对应的边的序号 


void init(int nn)//清理 
{
    for(int i = 0; i <= nn; i++)
        G[i].clear();
    edges.clear();
}

void AddEdge(int uu, int vv, int ww)//加边 
{
    edges.push_back(Edge(uu, vv, ww));
    int edgenum = edges.size();
    G[uu].push_back(edgenum - 1);
}

struct node//优先队列优化,dis小的先出队 
{
    int u, d;
    node() {};
    node(int uu, int dd): u(uu), d(dd) {};
    friend bool operator < (node a, node b)
    {
        return a.d > b.d;
    }
};

void dijkstra(int s)
{
    priority_queue<node> q;
    memset(dis, INF, sizeof(dis));//dis初始化为INF 
    dis[s] = 0;
    q.push(node(s, dis[s]));
    while(!q.empty())
    {
        node cur = q.top();
        q.pop();
        int from = cur.u;
        if(cur.d != dis[from])//减少了vis数组,表示该节点被取出来过 
            continue;
        for(int i = 0; i < G[from].size(); i++)//更新所有集合外点到集合的dis 
        {
            Edge e = edges[G[from][i]];
            if(dis[e.v] > dis[e.u] + e.w)
            {
                dis[e.v] = dis[e.u] + e.w;
                pre[e.v] = from;//存储父节点 
                q.push(node(e.v, dis[e.v]));//将有更新的dis加入到队列中 
            }
        }
    }
}
int main()
{
    int n, m;
    while(~scanf("%d%d", &n, &m) && n && m)
    {
        init(n);
        for(int i = 0; i < m; i++)
        {
            int u, v, w;
            scanf("%d%d%d", &u, &v, &w);
            AddEdge(u, v, w);
            AddEdge(v, u, w);
        }
        dijkstra(1);
        printf("%d\n", dis[n]);
    }
    return 0;
}

Floyd_Warshall

#include <iostream>
#include <stdio.h>
#include <string>
#include <string.h>
#include <queue>
#include <vector>
#define INF 0x3f3f3f3f

using namespace std;

int main()
{
    int n, m, s, t;
    while(~scanf("%d%d", &n, &m))
    {
        vector<vector<int> > dis(n);//vector二维可变长数组
        for(int i = 0; i < n; i++)
        {
            dis[i].resize(n, INF);//初始化设置dis[i]的长度,并用INF作为初始值
            dis[i][i] = 0;
        }
        for(int i = 0; i < m; i++)//输入边a,b两点的权值是x
        {
            int a, b, x;
            scanf("%d%d%d", &a, &b, &x);
            if(dis[a][b] > x)
                dis[a][b] = dis[b][a] = x;
        }
        scanf("%d%d", &s, &t);
        for(int k = 0; k < n; k++)
            for(int i = 0; i < n; i++)
                for(int j = 0; j < n; j++)
                {
                    if(dis[i][k] < INF && dis[k][j] < INF)
                        dis[i][j] = min(dis[i][j], dis[i][k] + dis[k][j]);
                }
        if(dis[s][t] != INF)//可以求任意两点间最短路
            printf("%d\n", dis[s][t]);
        else
            printf("-1\n");
    }
    return 0;
}

SPFA

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<vector>

#define inf 0x3f3f3f3f

using namespace std;

int dis[105],visit[105];
int n,m;

class Node
{
public:
    int e,v;
    Node(int a,int b){e = a,v = b;}
};

vector<Node>s[105];

void spfa()
{
    memset(dis,inf,sizeof(dis));
    memset(visit,0,sizeof(visit));
    dis[1] = 0;
    queue<int>q;
    q.push(1);
    visit[1] = true;
    while(!q.empty()){
        int u = q.front();
        q.pop();
        visit[u] = false;
        int num = s[u].size();
        for(int i = 0;i < num; i++){
            if(dis[u] + s[u][i].v > dis[s[u][i].e])
                continue;
            dis[s[u][i].e] = dis[u] + s[u][i].v;
            if(!visit[s[u][i].e]){
                q.push(s[u][i].e);
                visit[s[u][i].e] = true;
            }
        }
    }
}

int main()
{
 //   freopen("in.txt","r",stdin);
    while(cin>>n>>m){
        if(n == 0 && m == 0)
            break;
        for(int i = 1;i <= n; i++)
            s[i].clear();
        int a,b,c;
        for(int i = 1;i <= m; i++){
            cin>>a>>b>>c;
            s[a].push_back(Node(b,c));
            s[b].push_back(Node(a,c));//ÕâÀïÎÞÏò
        }
        spfa();
        cout<<dis[n]<<endl;
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值