dijkstra,SPFA,Floyd求最短路

來源:互聯網
上載者:User

標籤:style   blog   http   color   使用   os   strong   io   

Dijkstra:

裸的演算法,O(n^2),使用鄰接矩陣:

演算法思想:

定義兩個集合,一開始集合1隻有一個源點,集合2有剩下的點。

STEP1:在集合2中找一個到源點距離最近的頂點k:min{d[k]}

STEP2:把頂點k加入集合1中,同時修改集合2中的剩餘頂點j的d[j]是否經過k之後變短,若變短則修改d[j];

if d[k]+a[k,j]<d[j] then   d[j]=d[k]+a[k,j];

STEP3:重複STEP1,直到集合2為空白為止。

#include <iostream>#include <cstring>using namespace std;#define MAXINT 9999999int minx,minj,x,y,t,k,n,m,tmp;int v[1000],d[1000],a[1000][1000];int main(){    cin>>n>>m>>k;    memset(a,0,sizeof(a));    memset(d,MAXINT,sizeof(d));    memset(v,0,sizeof(v));    d[k]=0;    for (int i=1;i<=m;i++)    {        cin>>x>>y>>t;        a[x][y]=t;        a[y][x]=t;    }    for (int i=1;i<=n-1;i++)    {        minx=MAXINT;        for (int j=1;j<=n;j++)            if ((v[j]==0)&&(d[j]<minx))            {                minx=d[j];                minj=j;            }        v[minj]=1;        for (int j=1;j<=n;j++)            if ((v[j]==0)&&(a[minj][j]>0))            {                tmp=d[minj]+a[minj][j];                if (tmp<d[j])   d[j]=tmp;            }    }    for (int i=1;i<=n;i++)        cout<<d[i]<<" ";    cout<<endl;    return 0;}
View Code

 

Tips:上述STEP1可以用優先隊列最佳化

模版:

(使用鄰接表,Reference:http://www.cnblogs.com/qijinbiao/archive/2012/10/04/2711780.html)

eg:鄰接表

i:某條邊的起點  eg[i][j].x:從點i出發的第j條邊的終點  eg[i][j].d:這條邊的距離

#include <iostream>#include <cstdio>#include <queue>#include <vector>using namespace std;const int Ni = 10000;const int INF = 1<<27;struct node{    int x,d;    node(){}    node(int a,int b){x=a;d=b;}    bool operator < (const node & a) const    {        if(d==a.d) return x<a.x;        else return d > a.d;    }};vector<node> eg[Ni];int dis[Ni],n;void Dijkstra(int s){    int i;    for(i=0;i<=n;i++) dis[i]=INF;    dis[s]=0;    priority_queue<node> q;    q.push(node(s,dis[s]));    while(!q.empty())    {        node x=q.top();q.pop();        for(i=0;i<eg[x.x].size();i++)        {            node y=eg[x.x][i];            if(dis[y.x]>x.d+y.d)            {                dis[y.x]=x.d+y.d;                q.push(node(y.x,dis[y.x]));            }        }    }}int main(){    int a,b,d,m,k;    scanf("%d%d%d",&n,&m,&k);    for(int i=0;i<=n;i++) eg[i].clear();    while(m--)    {        scanf("%d%d%d",&a,&b,&d);        eg[a].push_back(node(b,d));        eg[b].push_back(node(a,d));    }    Dijkstra(k);    for (int i=1;i<=n;i++)        printf("%d\n",dis[i]);    return 0;}
View Code

STL優先隊列Reference:http://www.cnblogs.com/wanghetao/archive/2012/05/22/2513514.html

 

 

SPFA:

即用隊列最佳化過的Bellman-Ford

( Reference:http://blog.csdn.net/niushuai666/article/details/6791765 )

Pascal代碼...

var q,d:array[1..1000] of longint;    a:array[1..1000,1..1000] of longint;    visited:array[1..1000] of boolean;    head,tail,s,n,dt,i,j:longint;beginassign(input,‘spfa.in‘);reset(input);fillchar(d,sizeof(d),127 div 3);fillchar(visited,sizeof(visited),false);fillchar(a,sizeof(a),0);readln(s);d[s]:=0;readln(n);for i:=1 to n do for j:=1 to n do  begin  read(dt);  a[i,j]:=dt;  a[j,i]:=dt;{ if dt<>0 then   begin   if i=s then d[j]:=dt;   if j=s then d[i]:=dt;   end;  }  end;head:=0;q[1]:=s;visited[s]:=true;tail:=1;while head<tail do begin inc(head); visited[q[head]]:=false; for i:=1 to n do  begin  if (a[q[head],i]>0) and (d[q[head]]+a[q[head],i]<d[i]) then   begin   d[i]:=d[q[head]]+a[q[head],i];   if not visited[i] then    begin    inc(tail);    q[tail]:=i;    visited[i]:=true;    end;   end;  end; end;for i:=1 to n do write(d[i],‘ ‘);writeln;close(input);end.
View Code

 

Floyd:

多源最短路

//path[i,j]:用來輸出最短路徑//floydvar path,d:array[1..1000,1..1000] of longint;    n,k,i,j,st,en,x,y,tmp:longint;procedure dfs(i,j:longint);beginif path[i,j]>0 then begin dfs(i,path[i,j]); write(path[i,j],‘->‘); dfs(path[i,j],j); end;end;beginassign(input,‘floyd.in‘);reset(input);fillchar(d,sizeof(d),127 div 3);readln(n);for i:=1 to n do d[i,i]:=0;for i:=1 to n do for j:=1 to n do  path[i,j]:=-1;readln(st,en);while not eof do begin readln(x,y,tmp); d[x,y]:=tmp; d[y,x]:=tmp; path[x,y]:=0; path[y,x]:=0; end;for k:=1 to n do for i:=1 to n do  for j:=1 to n do   begin   if d[i,k]+d[k,j]<d[i,j] then    begin    d[i,j]:=d[i,k]+d[k,j];    path[i,j]:=k;    end;   end;writeln(d[st,en]);write(st,‘->‘);dfs(st,en);writeln(en);close(input);end.
View Code

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.