HDU 2544 最短路(Floyd/Dijkstra/SPFA)

来源:互联网 发布:考勤机怎么恢复数据 编辑:程序博客网 时间:2024/06/05 03:57

题目

http://acm.hdu.edu.cn/showproblem.php?pid=2544

题意:求从源点1到终点N的单源最短路径。

解题思路

单源最短路径的裸题,用来复习floyd和dijkstra。

AC代码

Floyd

算法复杂度:O(|V|^3)

#include <iostream>#include <algorithm>using namespace std;const int maxn = 105, INF = 1<<27;int dist[maxn][maxn];void Floyd(int n) //Floyd算法{    for (int k = 1; k <= n; ++k)        for (int i = 1; i <= n; ++i)            for (int j = 1; j <= n; ++j)                dist[i][j] = min(dist[i][j], dist[i][k] + dist[k][j]);}void init(int n) //初始化{    for (int i = 1; i <= n; ++i)    {        for (int j = 1; j <= n; ++j)        {            if(i == j) dist[i][j] = 0; //到自己为0            else dist[i][j] = INF; //其余为无穷大        }    }}int main(){    ios::sync_with_stdio(false);    int n, m;    while (cin >> n >> m && n && m)    {        init(n);        int t1,t2,cos;        for (int i = 0; i<m; ++i)        {            cin >> t1 >> t2 >> cos;            dist[t1][t2] = dist[t2][t1] = cos;        }        Floyd(n);        cout << dist[1][n] << endl;    }    return 0;}

最小优先队列Dijkstra

#include <iostream>#include <algorithm>#include <queue>#include <vector>using namespace std;const int maxn = 105, INF = 1<<27;struct edge{    int to, cost;    edge(){}    edge(int _to, int _cost)    {        to = _to;        cost = _cost;    }};typedef pair<int,int> P; //first是源点到该顶点的距离,second是顶点编号vector<edge> G[maxn]; //G[i]存放从i出发的边int dist[maxn]; //存放最短距离void dijkstra(int src) //最小优先队列优化的Dijkstra{    fill(dist, dist+maxn, INF);    priority_queue<P, vector<P>, greater<P> > q;    q.push(P(0, src));    dist[src] = 0;    while(!q.empty())    {        P out = q.top(); q.pop();        int pos = out.second, d = out.first; //pos是顶点编号,d是距离        if (d > dist[pos]) continue; //取出的不是最短距离        for (int i = 0; i < G[pos].size(); ++i)        {            edge &e = G[pos][i];            if (d + e.cost < dist[e.to])            {                dist[e.to] = d + e.cost;                q.push(P(dist[e.to], e.to));            }        }    }}int main(){    ios::sync_with_stdio(false);    int n, m;    while (cin >> n >> m && n && m)    {        for (int i = 0; i<=n; ++i)            G[i].clear();        for (int i = 0; i<m; ++i)        {            int c1, c2, cos;            cin >> c1 >> c2 >> cos;            G[c1].push_back(edge(c2, cos));            G[c2].push_back(edge(c1, cos));        }        dijkstra(1);        cout << dist[n] << endl;    }    return 0;}

SPFA

#include <iostream>#include <algorithm>#include <queue>using namespace std;const int maxn = 105, INF = 1<<27;int cost[maxn][maxn];bool visited[maxn]; //标记i是否在队列里int dist[maxn]; //记录最短距离int n, m;void SPFA(int s){    queue<int> q;    q.push(s);    dist[s] = 0;    visited[s] = true; //源点入队    while(!q.empty())    {        int out = q.front(); q.pop();        visited[out] = false; //出队后更新visited        for (int i = 1; i<=n; ++i) //松弛        {            if (dist[out] + cost[out][i] < dist[i])            {                dist[i] = dist[out] + cost[out][i];                if (!visited[i]) //松弛的点不在队列里则加入                {                    q.push(i);                    visited[i] = true;                }            }        }    }}void init(int n) //初始化{    for (int i = 1; i <= n; ++i)    {        for (int j = 1; j <= n; ++j)        {            if(i == j) cost[i][j] = 0; //到自己为0            else cost[i][j] = INF; //其余为INF        }    }    fill(dist, dist+maxn, INF);    fill(visited, visited+maxn, false);}int main(){    ios::sync_with_stdio(false);    while (cin >> n >> m && n && m)    {        init(n);        int t1,t2,cos;        for (int i = 0; i<m; ++i)        {            cin >> t1 >> t2 >> cos;            cost[t1][t2] = cost[t2][t1] = cos;        }        SPFA(1);        cout << dist[n] << endl;    }    return 0;}
原创粉丝点击