您的位置:首页 > 其它

[hdu 2544] 最短路(SPFA版)

2014-04-26 01:33 246 查看
Dijkstra算法通俗易懂,spfa的思想其实也就一两句话,如果i->j->k的距离小于i->k,那么dist[i->k] = dist[i->j->k],然后,因为i到k的距离变短了,有可能这个k结点能用来改进其他结点,所以要放在队列中等待下一步的距离判断。

#include<iostream>
#include<cstdio>
#include<queue>
using namespace std;

#define maxn 105
#define inf 0x3f3f3f3
struct node
{
int num;
int dis[70];
int next[70];
};

int n, m;

node mat[maxn];
int inque[maxn]; // 结点是否在队列中
int dist[maxn]; // 源点到各个结点的距离

void spfa(int st)
{
for(int i = 1; i <= n; i++) // 初始化距离
dist[i] = (i == st ? 0: inf);

memset(inque, false, sizeof(inque));
queue<int> q;
while(!q.empty()) q.pop();
q.push(st);
inque[st] = 1;
while(!q.empty())
{
int now = q.front();
for(int i = 0; i < mat[now].num; i++)
{
// 若a->b->c的消耗小于a->c, 则a->c的消耗是a->b->c的消耗
if(dist[now] + mat[now].dis[i] < dist[mat[now].next[i]])
{
dist[mat[now].next[i]] = dist[now] + mat[now].dis[i];
if(!inque[mat[now].next[i]]) // 这个节点松弛过且不在队列,则入队
{
q.push(mat[now].next[i]);
inque[mat[now].next[i]] = true;
}
}
}
q.pop();
inque[now] = false;
}
}

int main()
{
int a, b, dis;
while(~scanf("%d%d", &n, &m) && (n||m))
{
for(int i = 1; i <= n; i++)
mat[i].num = 0;

for(int i = 0; i < m; i++)
{
scanf("%d%d%d", &a, &b, &dis);
mat[a].next[mat[a].num] = b;
mat[a].dis[mat[a].num++] = dis;

mat[b].next[mat[b].num] = a;
mat[b].dis[mat[b].num++] = dis;
}
spfa(1);
printf("%d\n", dist
);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: