hdu1874暢通工程續——最短路(Dijkstra算法)(spfa算法)

題意:給你那個城市,再給你m個路段及長度。詢問你從start到end的最小距離。

思路:Dijkstra算法的模板。

我對Dijkstra的理解:

用二維數組模擬兩個城市之間的關係,然後用一個一維數組不斷更新起始點到各個城市的距離。

從與起始點相關的路中選出最短的城市,然後用這個城市去遍歷所有城市(已經用過的城市不會用的),凡是比一維數組中的距離近就更新一維數組,這樣就能把起始點與這些城市聯繫起來,並且是最近的。

不要以爲這樣就結束了,上述一次遍歷,還有許多城市沒有用到,爲了防止通過其他城市,到達終點的距離更近,要跑n-1次這樣的循環。目的就是找最近中最近的。

代碼::

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
const int inf = 1<<30;  //定義最大數 
using namespace std;
int n,m;
int map[300][300];
int mark[300],dis[300];
void Dijkstra(int s,int e)
{
int i,j,min,pos;
memset(mark,0,sizeof(mark));
mark[s]=1;//標記一下, 
for(i=0;i<n;i++)//用一位數組記錄start點到所有點的距離 
{
dis[i]=map[s][i];
}
for(i=1;i<n;i++)//核心代碼,不斷更新所有城市,跑一次更新一次 
{
min=inf;
for(j=0;j<n;j++)//選出每次更新最近的點 
{
if(dis[j]<min&&mark[j]==0)
{
min=dis[j];
pos=j;
}
}
mark[pos]=1;//標記篩選出來的點 
for(j=0;j<n;j++)//用篩選出來的點遍歷所有點的距離,方便查找或下一次選擇最近的點 
{
if(dis[pos]+map[pos][j]<dis[j]&&mark[j]==0)
{
dis[j]=dis[pos]+map[pos][j];
}
}
}
}
int main()
{
int i,j,x,y,z,start,end;
while(scanf("%d%d",&n,&m)!=EOF)
{
for(i=0;i<n;i++)//初始化二維數組 
{
for(j=0;j<n;j++)
{
map[i][j]=inf;
}
map[i][i]=0;
}
for(i=0;i<m;i++)//用二維數組記錄城市之間的距離 
{
scanf("%d%d%d",&x,&y,&z);
if(z<map[x][y])
{
map[x][y]=map[y][x]=z;
}
}
scanf("%d%d",&start,&end);
Dijkstra(start,end);
printf("%d\n",dis[end]==inf?-1:dis[end]);
}
return 0;
}

後面這個是時下比較流行的吧,關鍵的地方是前向星的使用,給大家一個網址,是學習前向星的,按照說的模擬一下,就能明白差不多了

http://blog.csdn.net/war___ning/article/details/46315037

本題代碼如下

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#include<queue>
#define inf 100000000
using namespace std;
struct node
{
int to,next,weight;
}city[100050];
int n,m;int cut;
int mark[10010];int head[10010];int dis[10010];


void add(int a,int b,int c)
{
city[cut].weight=c;
city[cut].to=b;
city[cut].next=head[a];
head[a]=cut++;
}
void spfa_bfs(int s)
{
int l,i;
queue<int>q;
mark[s]=1;
dis[s]=0;
while(!q.empty()) q.pop();
q.push(s);
while(!q.empty())
{
l=q.front();
q.pop();
mark[l]=0;
for(i=head[l];i+1;i=city[i].next)
{
if(city[i].weight+dis[l]<dis[city[i].to])
{
dis[city[i].to]=city[i].weight+dis[l];
if(mark[city[i].to]==0)
{
q.push(city[i].to);
mark[city[i].to]=1;
}
}
}
}
}
int main()
{
while(scanf("%d%d",&n,&m)!=EOF)
{
cut=0;
memset(head,-1,sizeof(head));
memset(city,0,sizeof(city));
for(int i=0;i<n;i++)
{
dis[i]=inf;mark[i]=0;
}
int x,y,z;
for(int i=0;i<m;i++)
{
scanf("%d%d%d",&x,&y,&z);
add(x,y,z);
add(y,x,z);
}
int start,end;
scanf("%d%d",&start,&end);
spfa_bfs(start);
if(dis[end]>=inf) printf("-1\n");
else printf("%d\n",dis[end]);
}
return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章