Hdu 2544 最短路 (Dijkstra+SPFA+Floyd模板)

来源:互联网 发布:网络报警qq 编辑:程序博客网 时间:2024/05/16 07:31

2014-5-5 更新:收藏夹里存的学习链接居然打不开了。。。重新找了个别人转的:最短路算法(Shortest Paths Algorithm) - D_Double's Journey


2013-7-18 更新:优化了最短路的模板,添加Dijkstra邻接矩阵写法


题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2544

最短路模板题。

Dijkstra

#pragma warning (disable: 4514 4786)#include <cstdio>#include <cstring> #include <algorithm> #include <queue>using namespace std;const int INF = 0x5fffffff;  //权值上限const int MAXPT = 102;       //顶点数上限const int MAXEG = 20002;     //边数上限//点存储1~ntemplate<typename Type>class Dijkstra     /*邻接表 + 优先队列 + Dijkstra求最短路*/{private:int n,e;    Type dis[MAXPT];int head[MAXPT];    bool visit[MAXPT];    struct Node{int v;Type dis;        Node () {}Node (int _v,Type _dis){v=_v;dis=_dis;}bool operator < (const Node a) const{return dis>a.dis;}};struct Edge{int v,next;Type w;Edge () {}Edge (int _v, int _next,Type _w){v=_v;next=_next;w=_w;}    }edges[MAXEG];public:    inline void init (int _n){         n = _n;e = 0;         memset(head,-1,sizeof(int) * (n+1));    }       inline void Add (int u,int v,Type w){         edges[e] = Edge(v, head[u], w);        head[u] = e++;    }       void print (){         for (int i=1;i<=n;i++){            printf("%d: ", i);             for (int j=head[i]; j!=-1; j=edges[j].next)                printf(" %d", edges[j].v);printf("\n");        }     }       Type dijkstra (int src, int des){         Node first, next;        priority_queue <Node> Q;        for (int i=0;i<=n;i++){             dis[i] = INF;             visit[i] = false;         }           dis[src]=0;        Q.push (Node(src, 0));          while (!Q.empty()){             first = Q.top();             Q.pop();             visit[first.v] = true;              for (int i=head[first.v] ; i!=-1 ; i=edges[i].next){                 if (visit[edges[i].v])continue;                next = Node(edges[i].v, first.dis + edges[i].w);                if (next.dis < dis[next.v]){                     dis[next.v] = next.dis;                     Q.push(next);                 }             }         }        return dis[des];     }};Dijkstra<int> ob;  int main (){int n,m;    while (~scanf("%d%d",&n,&m), n || m){ob.init(n);while (m--){int u,v,w;scanf("%d%d%d",&u,&v,&w);ob.Add(u,v,w);ob.Add(v,u,w);        }printf("%d\n",ob.dijkstra(1,n));}return 0; }


#include <cstdio>#include <cstring> #include <algorithm> #include <queue>using namespace std;const int INF = 0x5fffffff;  //权值上限const int MAXPT = 102;       //顶点数上限const int MAXEG = 20002;     //边数上限//点存储1~nclass Dijkstra     /*邻接表 + 优先队列 + Dijkstra求最短路*/{private:int n,e;    int dis[MAXPT], head[MAXPT];    int visit[MAXPT];    struct Node{int v,dis;        Node () {}Node (int _v,int _dis){v=_v;dis=_dis;}bool operator < (const Node a) const{return dis>a.dis;}};struct Edge{int v, w, next;Edge () {}Edge (int _v, int _next, int _w){v=_v;next=_next;w=_w;}    }edges[MAXEG];public:    inline void init (int vx){         n = vx;e = 0;         memset(head,-1,sizeof(int) * (vx + 1));    }       inline void Add (int u, int v, int w){         edges[e] = Edge(v, head[u], w);        head[u] = e++;    }       void print (){         for (int i=1;i<=n;i++){             printf("%d: ", i);             for (int j=head[i]; j!=-1; j=edges[j].next)                printf(" %d", edges[j].v);printf("\n");        }     }       int dijkstra (int src, int des){         Node first, next;        priority_queue <Node> Q;        for (int i=0;i<=n;i++){             dis[i] = INF;             visit[i] = false;         }           dis[src]=0;         Q.push (Node(src, 0));          while (!Q.empty()){             first = Q.top();             Q.pop();             visit[first.v] = true;              for (int i=head[first.v] ; i!=-1 ; i=edges[i].next){                 if (visit[edges[i].v])continue;                 next = Node(edges[i].v, first.dis + edges[i].w);                if (next.dis < dis[next.v]){                     dis[next.v] = next.dis;                     Q.push(next);                 }             }         }        return dis[des];     }}ob;   int main (){int n,m;    while (~scanf("%d%d",&n,&m), n || m){ob.init(n);while (m--){int u,v,w;scanf("%d%d%d",&u,&v,&w);ob.Add(u,v,w);ob.Add(v,u,w);        }printf("%d\n",ob.dijkstra(1,n));}return 0; }

SPFA

#include <iostream>#include <cstdio>#include <cstring>#include <queue>using namespace std;const int MAXPT = 105; const int MAXEG = 20005; const int INF = 0x3fffffff;template<typename Type>class SPFA{private:int n,e;     Type dis[MAXPT];int head[MAXPT],cnt[MAXPT]; //cnt[i]>n则表示有负环    bool visit[MAXPT];    struct Edge{int v,next;Type w;Edge () {}Edge (int _v, int _next, Type _w){v=_v;next=_next;w=_w;}    }edges[MAXEG];public:    void init (int _n){         n = _n;e = 0;         for (int i=0;i<=n;i++) {            head[i] = -1;            visit[i] = false;            dis[i] = INF;cnt[i] = 0;        }     }       inline void Add (int u,int v,Type w){         edges[e] = Edge(v,head[u],w);        head[u] = e++;    }     Type spfa (int src, int des){         queue<int> que;        dis[src] = 0;         que.push(src);         visit[src] = true;         while (!que.empty()){             int u = que.front();            que.pop ();            visit[u] = false;             for (int i = head[u]; i != -1; i = edges[i].next){                 int v = edges[i].v;if (dis[v] == INF || dis[u]+edges[i].w < dis[v]){dis[v]=dis[u]+edges[i].w;cnt[u]++;if (cnt[u]>=n) return -1; //负环if (visit[v]==false){visit[v] = true;que.push(v);}}}        }        return dis[des];    }};SPFA<int> ob;  int main (){     int n,m;     while (~scanf("%d%d", &n, &m), n || m){        ob.init(n);        int a, b, c;        for (int i=0;i<m;i++){            scanf("%d%d%d",&a,&b,&c);            ob.Add(a,b,c);            ob.Add(b,a,c);        }        printf("%d\n",ob.spfa(1,n));    }     return 0; }

#include <iostream>#include <cstdio>#include <cstring>#include <queue>using namespace std;const int MAXPT = 105; const int MAXEG = 20005; const int INF = 0x5fffffff;  class SPFA{private:int n,e;     int dis[MAXPT],head[MAXPT];int cnt[MAXPT]; //cnt[i]>n则表示有负环    bool visit[MAXPT];    struct Edge{int v,w,next;Edge () {}Edge (int _v, int _next, int _w){v=_v;next=_next;w=_w;}    }edges[MAXEG];public:    void init (int vn){         n = vn;e = 0;         for (int i=0;i<=n;i++) {            head[i] = -1;            visit[i] = false;            dis[i] = INF;cnt[i] = 0;        }     }       inline void Add (int u, int v, int w){         edges[e] = Edge(v,head[u],w);        head[u] = e++;    }     int spfa (int src, int des){         queue<int> que;         dis[src] = 0;         que.push(src);         visit[src] = true;         while (!que.empty()){             int u = que.front();             que.pop();             visit[u] = false;             for (int i = head[u]; i != -1; i = edges[i].next){                 int v = edges[i].v;if (dis[v] == INF || dis[u]+edges[i].w < dis[v]){dis[v]=dis[u]+edges[i].w;cnt[u]++;if (cnt[u]>=n)return -1;if (visit[v]==false){visit[v] = true;que.push(v);}}}        }        return dis[des];    }}ob;   int main (){     int n,m;     while (~scanf("%d%d", &n, &m), n || m){        ob.init(n);        int a, b, c;        for (int i=0;i<m;i++){            scanf("%d%d%d",&a,&b,&c);            ob.Add(a,b,c);            ob.Add(b,a,c);        }        printf("%d\n",ob.spfa(1,n));    }     return 0; }

Floyd

#include <cstdio>#define min(x,y) ((x)<(y)?(x):(y))const int INF=0x3fffffff;   //假想无穷大过大处理过程中会越界……int map[105][105];int n,m;void Floyd (){for (int i=1;i<=n;i++)for (int j=1;j<=n;j++)for (int k=1;k<=n;k++)map[j][k]=min(map[j][k],map[j][i]+map[i][k]);}int main (){    while (~scanf("%d%d", &n, &m), n || m){        for (int i = 1; i <= n; i++)            for (int j = i; j <= n; j++)                map[i][j] = map[j][i] =INF;        while (m--){            int u, v, w;            scanf("%d%d%d", &u, &v, &w);            map[u][v] = map[v][u] = w;        }        Floyd ();        printf("%d\n",map[1][n]);    }return 0;}


Dijkstra 邻接矩阵写法(非本题)

#include <cstdio>#include <cstring> #include <algorithm> #include <queue>using namespace std;const int INF = 0x3fffffff;  //权值上限const int MAXPT = 102;       //顶点数上限typedef pair <int,int> ele;class Dijkstra     /*邻接矩阵 + 优先队列 + Dijkstra求最短路*/{private:int map[MAXPT][MAXPT];bool vis[MAXPT];int dis[MAXPT];int n;public:void init (int num){n=num;for (int i=1;i<=n;i++)for (int j=1;j<=n;j++){if (i==j)map[i][j]=0;elsemap[i][j] = INF;}memset (dis,0,sizeof(dis));memset (vis,false,sizeof(vis));}void Add (int u,int v,int w){if (w<map[u][v])map[u][v]=w;}int dijkstra (int src,int end){int i;for (i=1;i<=n;i++)dis[i] = INF;dis[src] = 0;priority_queue < ele,vector<ele>,greater<ele> >q;  //优先队列:小顶堆q.push (make_pair(dis[src],src));while ( !q.empty() ){ele t = q.top();q.pop();int now = t.second;if ( vis[now] )continue;vis[now] = true;for (i=1; i<=n; i++)if (!vis[i] && map[now][i]<INF && dis[i] > dis[now]+map[now][i]){dis[i] = dis[now]+map[now][i];q.push(make_pair(dis[i],i));}}return dis[end];}}ob;int main ()  {      int n,m;      while (~scanf("%d%d",&n,&m), n || m)      {          ob.init(n);          while (m--)          {              int u,v,w;              scanf("%d%d%d",&u,&v,&w);              ob.Add(u,v,w);              ob.Add(v,u,w);          }        printf("%d\n",ob.dijkstra(1,n));      }      return 0;   }  


原创粉丝点击