最短路问题

来源:互联网 发布:好的软件源 编辑:程序博客网 时间:2024/06/05 04:04

这是hihocoder 的1081题,我先看了算法书,刚好看到图论的这个最短路问题。就想着练练手。

这里有两种算法:

1,Bellman-Ford算法

就是将每一条边取出,然后更新最短路。直到无法更新为止,输出终点最短路即可。挺容易理解的。但是复杂度较高,为O(n*m)

以下是代码

#include <stdio.h>#include <iostream>#include <cstring>#include <cmath>#include <algorithm>#include <queue>#include <sstream>#define INF 1e9using namespace std;typedef long long ll;struct edge{    int from;    int to;    int cost;};//这是要遍历的边edge es[10005];int n,m,s,k,d[5000];//点的个数,边的个数,起点,终点,各点最短路void short_path(int a){    fill(d+1,d+n+1,INF);    d[a]=0;    while (1)    {        bool update = false;        for (int i = 0;i < m;i++)        {            edge q = es[i];            if(d[q.from]!=INF&&d[q.to]>d[q.from]+q.cost){                update = true;                d[q.to]=d[q.from]+q.cost;            }            if(d[q.to]!=INF&&d[q.from]>d[q.to]+q.cost){                update = true;                d[q.from]=d[q.to]+q.cost;            }//由于边是无向的,于是需要正反都算        }        if(!update)            break;//如果更新完毕就退出    }}int main(void){    while (scanf("%d %d %d %d",&n,&m,&s,&k)!=EOF)    {        for (int i = 0;i < m;i++)        {            scanf("%d %d %d",&es[i].from,&es[i].to,&es[i].cost);        }        short_path(s);        cout<<d[k]<<endl;    }    return 0;}
2、Dijkstra算法

这个我自己觉得难理解点,但是hihocoder 貌似说挺容易理解的

不过确实如果细细看一遍还是不难理解的

大致意思就是说以从一个点开始找周围最短路的点,然后给予给其点标记最短路,代码里面用的是d[ i ]数组,直到全部标记完为止。

代码如下:

#include <stdio.h>#include <iostream>#include <cstring>#include <cmath>#include <algorithm>#include <queue>#include <sstream>#define INF 1e9using namespace std;typedef long long ll;int n,m,s,k;bool used[1005];//用于判断点是否用过int d[1005];//各点最短路int cost[1005][1005];//图void dijkstra(){    fill(d+1,d+n+1,INF);    fill(used+1,used+n+1,false);    d[s] = 0;    while (1)    {        int v = -1;        for (int u = 1;u <= n;u++)        {            //cout<<d[u]<<endl;            if(!used[u]&&(v==-1||d[u]<d[v]))               v = u;        }        if(v == -1)        {            break;        }        used[v] = true;        for (int u = 1;u <= n;u++)        {            d[u] = min(d[u],d[v]+cost[v][u]);        }    }}int main(void){    while (scanf("%d %d %d %d",&n,&m,&s,&k)!=EOF)    {        for (int i = 1;i <= n;i++)        {            fill(cost[i]+1,cost[i]+n+1,INF);        }        for (int i = 0;i < m;i++)        {            int p,q,u;            scanf("%d %d %d",&p,&q,&u);            cost[p][q]=cost[q][p]=min(u,cost[p][q]);        }        dijkstra();        cout<<d[k]<<endl;    }    return 0;}


1 0
原创粉丝点击