您的位置:首页 > 其它

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

2013-03-09 17:37 746 查看
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~n
template<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~n
class 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]
);
    }
	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;
				else
					map[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;   
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: