hdu 1874 畅通工程续(最短路Dij邻接表)

来源:互联网 发布:java获取本地端口号 编辑:程序博客网 时间:2024/06/03 23:05

题目地址

题目大意:给出n个点m条边,并给出起点和终点,求起点到终点的最短路

解题思路:1.没有负边权

                  2.复杂度mlg(n)(n为点的个数,m为边的条数)

                  3.起点固定,不断更新终点,若要输出路径,则需要逆序输出

                  4.适用于有向图和无向图

                  5.用优先队列来优化,定义按照到起点的距离从小到大排序(greater)

#include <iostream>#include <cstdio>#include <cmath>#include <cstring>#include <vector>#include <queue>#include <utility>using namespace std;const int maxn = 210;///点的个数const int maxm = 4010;///边的个数const int INF = 0xfffffff;int n,m,cnt;///有n个点,m条边int vis[maxn],dis[maxn],head[maxn];typedef pair<int,int> pii;struct edge{    int to,val,next;}e[maxm];void add(int from,int to,int  val){    e[cnt].to=to;    e[cnt].val=val;    e[cnt].next=head[from];    head[from]=cnt++;}void Dijkstra(int s){    memset(vis,0,sizeof(vis));    for(int i = 0 ; i < n ; i++) /*初始化点的距离*/        dis[i] = INF;    dis[s] = 0;    priority_queue<pii,vector<pii>,greater<pii> > pq;    pq.push(make_pair(dis[s],s));    while(!pq.empty())    {        pii u = pq.top();        pq.pop();        int x = u.second; //点        if(vis[x])  continue;        vis[x] = 1;        for(int i = head[x]; i != -1; i = e[i].next)//对每条边及其有相同点(x)的其他边进行更新        {            int v = e[i].to;            if(dis[v] > dis[x]+e[i].val && !vis[v])            {                dis[v] = dis[x] + e[i].val;                pq.push(make_pair(dis[v],v));            }        }     }}int main(){    while(scanf("%d%d",&n,&m) != EOF)    {        cnt = 0;        memset(head,-1,sizeof(head));        for(int i=0;i<m;i++)        {            int from,to,val;            scanf("%d%d%d",&from,&to,&val);            add(from,to,val);            add(to,from,val);        }        int s,t;        scanf("%d%d",&s,&t);        Dijkstra(s);        dis[t]==INF ? printf("-1\n") : printf("%d\n",dis[t]);    }    return 0;}


 

0 0