【模板】最短路

迪杰斯特拉+堆优化

#include<bits/stdc++.h>
using namespace std;
const int MAXN = 100005;
const int MAXM = 200005;
struct edge{
    int to, next;
    long long w;
}e[MAXM];
int cnt, head[MAXM];
int n, m, s;
priority_queue< pair<int, int> > q;
int d[MAXM], vis[MAXM]; //vis[]代表一个点到集合的距离

void add(int u, int v, long long val)
{
    e[++cnt].to = v;
    e[cnt].next = head[u];
    e[cnt].w = val;
    head[u] = cnt;
}

int main()
{
    cin >> n >> m >> s;
    for(int i = 1; i <= m; i++)
    {
        int a, b;
        long long c;
        cin >> a >> b >> c;
        add(a, b, c);
    }
    
    for(int i = 1; i <= n; i++)
      d[i] = 2147483647;
    int p = s;
    q.push(make_pair(0, p));
    d[p] = 0;
    while(!q.empty())
    {
        int x = q.top().second; 
        q.pop();
        if(vis[x]) continue;
        vis[x] = 1;
        for(int i = head[x]; i; i = e[i].next)
        {
            if( d[e[i].to] > (d[x] + e[i].w))
            {
                d[e[i].to] = (d[x] + e[i].w);
                q.push(make_pair(-d[e[i].to], e[i].to));    
            }
        }
    }
    for(int i = 1; i <= n; i++)
        cout << d[i] << " ";
    return 0;
} 

 floyed

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<algorithm>
using namespace std;
const int inf = 0x3f3f3f3f;
int dis[205][205];
int n, m, k, x, y, z, a, b,q;
int main()
{
    cin >> n >> m >> q;
    for(int i = 1; i <= n; i++)
        for(int j = 1; j <= n; j++)
        {
            if(i == j) dis[i][j] = 0;
            else dis[i][j] = inf;
        }
    for(int i = 1; i <= m; i++)
    {
        cin >> x >> y >> z;
        dis[x][y] = min(dis[x][y], z);
    }
    for(int k = 1; k <= n; k++)
        for(int i = 1; i <= n; i++)
            for(int j = 1; j <= n; j++)
                dis[i][j] = min(dis[i][j], dis[i][k]+dis[k][j]) ;
    for(int i = 1; i <= q; i++)
    {
        cin >> a >> b;
        if(dis[a][b] > inf/2) cout << "impossible" << endl;
        else cout << dis[a][b] << endl;
    }            
    return 0;
}

 spfa

#include<iostream>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<queue>
using namespace std;
const int maxn = 100005;
const int inf = 0x3f3f3f3f;
struct edge{
    int to, nxt, w;
}e[maxn];
int head[maxn], cnt;
int dis[maxn], vis[maxn];
queue<int> q;
int n, m, x, y, z;

void add(int u, int v, int val)
{
    e[++cnt].to = v;
    e[cnt].w = val;
    e[cnt].nxt = head[u];
    head[u] = cnt;
}

int main()
{
    cin >> n >> m;
    for(int i = 1; i <= m; i++)
    {
        cin >> x >> y >> z;
        add(x, y, z);
    }
    for(int i = 1; i <= m; i++)
        dis[i] = inf;
    q.push(1); vis[1] = 1; dis[1] = 0;
    while(!q.empty())
    {
        int now = q.front();
        q.pop();
        vis[now] = 0;   //注意因为now这个点已经出了队列,所以vis[now] = 0;   vis[]表示一个点是否在队列里
        for(int i = head[now]; i; i = e[i].nxt)
        {
            if(dis[e[i].to] > dis[now]+e[i].w)
            {
                dis[e[i].to] = dis[now]+e[i].w;
                if(!vis[e[i].to]) 
                {
                    q.push(e[i].to);
                    vis[e[i].to] = 1;
                }
            }
        }
    }
    if(dis[n] == inf) cout << "impossible";
    else cout << dis[n];
    return 0;
}

 

posted @ 2019-11-10 10:25  ATKevin  阅读(118)  评论(0)    收藏  举报