HDU 2544 最短路 (模板题)

来源:互联网 发布:淘宝店铺怎么注销 编辑:程序博客网 时间:2024/06/05 00:19

Dijkstra+邻接表+优先队列

#include <iostream>#include <cstring>#include <queue>using namespace std;const int MAXN=110;const int MAXM=10010;const int INF=99999999;int edgenum=0,n,m,head[MAXN],book[MAXN];struct HeapNode{    int num,dist;//num为结点编号,dist为最短路径估计数组    bool operator < (const HeapNode &a) const//dist小的优先出队    {        return (dist>a.dist);    }}node[MAXN];//优先队列中的结点数组struct Edge{    int v,next,w;//v为边的终点,w为边的权值,next为下一条边编号}edge[2*MAXM];void Add_Edge(int u,int v,int w)//构建邻接表{    edge[++edgenum].v=v;    edge[edgenum].w=w;    edge[edgenum].next=head[u];//下一条边编号    head[u]=edgenum;//head[u]为u号结点连出的第一条边编号}void Dijkstra(){    for (int i=1;i<=n;i++)//初始化dist[]数组    {        node[i].dist=(i==1?0:INF);        node[i].num=i;    }    memset(book,0,sizeof(book));    priority_queue<HeapNode> Q;    Q.push(node[1]);    while (!Q.empty())    {        HeapNode p=Q.top();//取出当前离源点最近的点        Q.pop();        int u=p.num;        if (book[u]) continue;//防止重复入队        book[u]=1;//源点到u的最短路已确定        for (int t=head[u];t!=-1;t=edge[t].next)//扫描u结点的所有出边        {            int v=edge[t].v;            int w=edge[t].w;            if (node[v].dist>node[u].dist+w)//判断是否松弛成功            {                node[v].dist=node[u].dist+w;                Q.push(node[v]);            }         }    }}int main(){    int a,b,c,i;    while  (cin>>n>>m)    {        if (!n&&!m) break;        edgenum=0;        for (i=1;i<=n;i++)//head[]初始化            head[i]=-1;        for (i=1;i<=m;i++)        {            cin>>a>>b>>c;            Add_Edge(a,b,c);            Add_Edge(b,a,c);//注意要建双向边        }        Dijkstra();        cout<<node[n].dist<<endl;    }    return 0;}

邻接表+SPFA

#include <iostream>#include <cstring>#include <queue>using namespace std;const int MAXN=110;const int MAXM=10010;const int INF=99999999;int edgenum=0,n,m,head[MAXN],book[MAXN];struct QNode{    int num,dist;//num为结点编号,dist为最短路径估计数组}node[MAXN];//队列结点struct Edge{    int v,next,w;}edge[2*MAXM];void Add_Edge(int u,int v,int w)//构建邻接表{    edge[++edgenum].v=v;    edge[edgenum].w=w;    edge[edgenum].next=head[u];    head[u]=edgenum;}void SPFA(){    for (int i=1;i<=n;i++)    {        node[i].dist=(i==1?0:INF);        node[i].num=i;    }    memset(book,0,sizeof(book));//book[i]判断i结点是否在队列中    queue<QNode> Q;    Q.push(node[1]);    book[1]=1;    while (!Q.empty())    {        QNode p=Q.front();        Q.pop();        int u=p.num;        book[u]=0;//u已不在队列中,有可能之后再次入队        for (int t=head[u];t!=-1;t=edge[t].next)        {            int v=edge[t].v;            int w=edge[t].w;            if (node[v].dist>node[u].dist+w)//判断是否松弛成功            {                node[v].dist=node[u].dist+w;                if (!book[v])//如果v不在队列中,将其入队                {                    Q.push(node[v]);                    book[v]=1;                }            }         }    }}int main(){    int a,b,c,i;    while  (cin>>n>>m)    {        if (!n&&!m) break;        edgenum=0;        for (i=1;i<=n;i++)            head[i]=-1;        for (i=1;i<=m;i++)        {            cin>>a>>b>>c;            Add_Edge(a,b,c);            Add_Edge(b,a,c);        }        SPFA();        cout<<node[n].dist<<endl;    }    return 0;}
0 0