poj 2387 最短路径 **dijkstra模板

来源:互联网 发布:淘宝评价语20字 编辑:程序博客网 时间:2024/06/06 20:27

真是一道神奇的题目,已经注意了重边的问题,但是还是各种WA

后来不用优先队列写了dijkstra算法,AC了

然后又改用优先队列写,AC了。。好奇怪,为什么一开始各种WA呢??不明白

#include <iostream>#include <vector>#include <map>#include <list>#include <set>#include <deque>#include <stack>#include <queue>#include <algorithm>#include <cmath>#include <cctype>#include <cstdio>#include <iomanip>#include <cmath>#include <cstdio>#include <iostream>#include <string>#include <sstream>#include <cstring>#include <queue>using namespace std;///宏定义const int  INF = 1000000000;const int MAXN = 2570;const int maxn = MAXN;///全局变量 和 函数int T, N;int g[maxn][maxn];struct node{int id;int dist;};int n;bool operator < (const node& t1, const node& t2){return t1.dist > t2.dist;}int solve(int start, int dest, int type){int i, j;bool done[maxn];int d[maxn];if (type == 0){for (i = 1; i <= n; i++){d[i] = INF;}d[start] = 0;memset(done, false, sizeof(done));/*for (i = 1; i <= n - 1; i++){int minpos = -1;int minval = INF;for (j = 1; j <= n; j++){if (!done[j] && d[j] < minval){minval = d[j];minpos = j;}}if (minpos == -1)return d[dest];done[minpos] = true;for (j = 1; j <= n; j++){if (g[minpos][j] != INF && d[j] > d[minpos] + g[minpos][j]){d[j] = d[minpos] + g[minpos][j];}}}*/node temp;temp.id = start, temp.dist = d[start];priority_queue<node> q;q.push(temp);while (!q.empty()){int curid = q.top().id;q.pop();if (done[curid])continue;done[curid] = true;for (i = 1; i <= n; i++){if (g[curid][i] != INF && d[i] > d[curid] + g[curid][i]){d[i] = d[curid] + g[curid][i];node tmp;tmp.id = i;tmp.dist = d[i];q.push(tmp); }}}}return d[dest];}int main(){///变量定义int i, j;while (scanf("%d %d", &T, &N) != EOF){n = N;for (i = 0; i < maxn; i++)for (j = 0; j < maxn; j++)g[i][j] = INF;for (i = 0; i < T; i++){int from, to, dist;scanf("%d %d %d", &from, &to, &dist);if (g[from][to] > dist){g[from][to] = g[to][from] = dist;}}int ans = solve(N, 1, 0);printf("%d\n", ans);}///结束return 0;}

再贴个邻接链表加优先队列的算法实现,显然速度比邻接矩阵要快的多

#include <iostream>#include <vector>#include <map>#include <list>#include <set>#include <deque>#include <stack>#include <queue>#include <algorithm>#include <cmath>#include <cctype>#include <cstdio>#include <iomanip>#include <cmath>#include <cstdio>#include <iostream>#include <string>#include <sstream>#include <cstring>#include <queue>using namespace std;///宏定义const int  INF = 1000000000;const int MAXN = 201000;const int maxn = MAXN;///全局变量 和 函数int t, n;int first[maxn];int u[maxn], v[maxn], w[maxn], next[maxn];int d[maxn];int done[maxn];struct Node{    int id;    int dist;};bool operator < (const Node& t1, const Node& t2){    return t1.dist > t2.dist;}int dijkstra(int start, int dest){    int i, j;    for(i = 1; i <= n; i++)        d[i] = INF;    d[start] = 0;    memset(done, false, sizeof(done));    Node node;    node.id = start;    node.dist = d[start];    priority_queue<Node> q;    q.push(node);    while(!q.empty())    {        Node tmp = q.top();        q.pop();        int curid = tmp.id;        if(done[curid])            continue;        done[curid] = true;        for(int e = first[curid]; e != -1; e = next[e])        {            if(d[v[e]] > d[curid] + w[e])            {                d[v[e]] = d[curid] + w[e];                Node temp;                temp.id = v[e];                temp.dist = d[v[e]];                q.push(temp);            }        }    }    return d[dest];}int main(){///变量定义int i, j;    while(scanf("%d %d", &t, &n) != EOF)    {        for(i = 1; i <= n; i++)        {            first[i] = -1;        }        int cnt = 0;        for(i = 0; i < t; i++)        {            int from, to, weight;            scanf("%d %d %d", &from, &to, &weight);            u[cnt] = from;            v[cnt] = to;            w[cnt] = weight;            next[cnt] = first[u[cnt]];            first[u[cnt]] = cnt;            cnt++;            u[cnt] = to;            v[cnt] = from;            w[cnt] = weight;            next[cnt] = first[u[cnt]];            first[u[cnt]] = cnt;            cnt++;        }        int ans = dijkstra(n, 1);        printf("%d\n", ans);    }///结束return 0;}


再贴一个 bellman ford算法,不同之处在于采用FIFO的队列

依据:如果存在最短路,则必然在有限次数(至多n-1)此内不能再进行松弛,详细见CLRS

#include <iostream>#include <vector>#include <map>#include <list>#include <set>#include <deque>#include <stack>#include <queue>#include <algorithm>#include <cmath>#include <cctype>#include <cstdio>#include <iomanip>#include <cmath>#include <cstdio>#include <iostream>#include <string>#include <sstream>#include <cstring>#include <queue>using namespace std;///宏定义const int  INF = 1000000000;const int MAXN = 201000;const int maxn = MAXN;///全局变量 和 函数int t, n;int first[maxn];int u[maxn], v[maxn], w[maxn], next[maxn];int d[maxn];int done[maxn];struct Node{    int id;    int dist;};bool operator < (const Node& t1, const Node& t2){    return t1.dist > t2.dist;}int dijkstra(int start, int dest){    int i, j;    for(i = 1; i <= n; i++)        d[i] = INF;    d[start] = 0;    memset(done, false, sizeof(done));    queue<int> qq;    bool inq[maxn];    memset(inq, false, sizeof(inq));    qq.push(start);    while(!qq.empty())    {        int curid = qq.front();        qq.pop();        inq[curid] = false;        for(int e = first[curid]; e != -1; e = next[e])        {            if(d[v[e]] > d[curid] + w[e])            {                d[v[e]] = d[curid] + w[e];                if(!inq[v[e]])                {                    inq[v[e]] = true;                    qq.push(v[e]);                }            }        }    }    return d[dest];}int main(){///变量定义int i, j;    while(scanf("%d %d", &t, &n) != EOF)    {        for(i = 1; i <= n; i++)        {            first[i] = -1;        }        int cnt = 0;        for(i = 0; i < t; i++)        {            int from, to, weight;            scanf("%d %d %d", &from, &to, &weight);            u[cnt] = from;            v[cnt] = to;            w[cnt] = weight;            next[cnt] = first[u[cnt]];            first[u[cnt]] = cnt;            cnt++;            u[cnt] = to;            v[cnt] = from;            w[cnt] = weight;            next[cnt] = first[u[cnt]];            first[u[cnt]] = cnt;            cnt++;        }        int ans = dijkstra(n, 1);//bellman ford非dij        printf("%d\n", ans);    }///结束return 0;}

Floyd 算法 超时了 TLE

#include <iostream>#include <vector>#include <map>#include <list>#include <set>#include <deque>#include <stack>#include <queue>#include <algorithm>#include <cmath>#include <cctype>#include <cstdio>#include <iomanip>#include <cmath>#include <cstdio>#include <iostream>#include <string>#include <sstream>#include <cstring>#include <queue>using namespace std;///宏定义const int  INF = 10000000;const int MAXN = 2010;const int maxn = MAXN;///全局变量 和 函数int t, n;//int first[maxn];//int u[maxn], v[maxn], w[maxn], next[maxn];//int d[maxn];//int done[maxn];int dd[maxn][maxn]; //Floyd算法阵void Floyd(){    int i, j, k;    for(k = 1; k <= n; k++)    {        for(i = 1; i <= n; i++)        {            for(j = 1; j <= n; j++)            {  //              if(dd[i][j] < INF && dd[k][j] < INF)  //              {                    if(dd[i][j] > dd[i][k] + dd[k][j])                        dd[i][j] = dd[i][k] + dd[k][j];  //              }            }        }    }}int main(){///变量定义int i, j;    while(scanf("%d %d", &t, &n) != EOF)    {        for(i = 1; i <= n; i++)        {            for(j = 1; j <= n; j++)            {                if(i != j)                    dd[i][j] = INF;                else                    dd[i][j] = 0;            }        }        for(i = 0; i < t; i++)        {            int from, to, weight;            scanf("%d %d %d", &from, &to, &weight);            if(dd[from][to] > weight)                dd[from][to] = dd[to][from] = weight;        }        Floyd();        int ans = dd[n][1];        printf("%d\n", ans);    }///结束return 0;}


最后再贴一个大神的dij的模板,非常好用

#include <iostream>#include <vector>#include <map>#include <list>#include <set>#include <deque>#include <stack>#include <queue>#include <algorithm>#include <cmath>#include <cctype>#include <cstdio>#include <iomanip>#include <cmath>#include <cstdio>#include <iostream>#include <string>#include <sstream>#include <cstring>#include <queue>using namespace std;///宏定义const int  INF = 10000000;const int MAXN = 1257;const int maxn = MAXN;///全局变量 和 函数struct Edge{int from;int to;int dist;};struct HeapNode{int d, u;bool operator < (const HeapNode& rhs) const{return d > rhs.d;}};struct Dijkstra{int n, m;             //点数和边数vector<Edge> edges;   //边列表vector<int> G[maxn];  //每个结点出发的边编号bool done[maxn];      //是否已永久编号int d[maxn];          //s到各个点的距离int p[maxn];          //最短路中的上一条边 (打印结果用)void init(int n){this->n = n;for (int i = 0; i <= n; i++)G[i].clear();edges.clear();}void AddEdge(int from, int to, int dist){    Edge tmp;    tmp.from = from;    tmp.to = to;    tmp.dist = dist;edges.push_back(tmp);m = edges.size();G[from].push_back(m - 1);}void dijkstra(int s){priority_queue<HeapNode> Q;for (int i = 0; i <= n; i++)d[i] = INF;d[s] = 0;memset(done, 0, sizeof(done));HeapNode tmp;tmp.d = 0;tmp.u = s;Q.push(tmp);while (!Q.empty()){HeapNode x = Q.top();Q.pop();int u = x.u;if (done[u])continue;done[u] = true;for (int i = 0; i < G[u].size(); i++){Edge &e = edges[G[u][i]];if (d[e.to] > d[u] + e.dist){d[e.to] = d[u] + e.dist;p[e.to] = G[u][i];HeapNode temp;temp.d = d[e.to];temp.u = e.to;Q.push(temp);}}}}};///int T, N;int main(){///变量定义int i, j;    while(scanf("%d %d", &T, &N) != EOF)    {        Dijkstra dij;        dij.init(N);        for(i = 0; i < T; i++)        {            int from, to, dist;            scanf("%d %d %d", &from, &to, &dist);            dij.AddEdge(from, to, dist);            dij.AddEdge(to, from, dist);        }        dij.dijkstra(N);        printf("%d\n", dij.d[1]);    }///结束return 0;}