传送:------- http://cdn.ac.nbutoj.com/Problem/view.xhtml?id=1137
题意: 这题 因为数据真的很小 我只是想通过这题 来介绍下 用 链式前向星来写spfa
关于 什么是链式前向星 可以自行百度
我这里介绍下它的基本用法 通过我和超神的 2篇很水的介绍
touch me touch me
你可以先去看完 这2篇 好好理解下 之后再继续读下去 反正它也不会消失 是吧
关于 spfa 你同样可以参考下 下面这篇很水的介绍
click it
PS: 这里我偷懒了 直接搬了自己写过的一些心得 原谅我的 懒惰 当然 那篇 对于 链式前向星的很详细的介绍 出自超神 超神 超神
突然 发现 凭借上述的东西 。。 我已经没有什么好继续写下去的了。。
先贴下代码 将我在写的过程中 遇到的问题顺便注释出来
#include <iostream> #include <cstring> #include <algorithm> #include <queue> using namespace std; const int inf = 0x3f3f3f3f; // 顺便提下 这是个很好的设置无穷大 它可以尽可能地避免 数值溢出 int num , n; struct graph { int to; int dist; int next; }edge[30]; int head[30]; bool vis[30]; int dis[30]; void addedge(int from , int to , int dist ) { edge[num].to = to; edge[num].dist = dist; edge[num].next = head[from]; head[from] = num; num++; } void spfa( int begin ) { int i , now; for( i = 0; i<n ; i++ ) { dis[i] = (i==begin) ? 0 : inf; } queue<int>q; while( !q.empty() ) q.pop(); q.push(begin); vis[begin] = true; while( !q.empty() ) { now = q.front(); for( i = head[now] ; i!=-1 ; i=edge[i].next ) { //这里 就是我找了好久才发现的错误 下面的进行松弛判断的操作 千万不要写成 dis[i] 而是 dis[now] //原因的话呢 就是 因为 i 是不断在变化的 而我们所要进行更新某个点到其余点的距离 //所以呢 就一定要写 dis[now] 这样理解起来可能是简单点的 如果你能很好的理解上面的spfa和链式前向星 //就会可以有自己的理解了 if( dis[now] + edge[i].dist < dis[ edge[i].to ] ) { dis[ edge[i].to ] = dis[now] + edge[i].dist; if( !vis[ edge[i].to ] ) { q.push( edge[i].to ); vis[ edge[i].to ] = true; } } } q.pop(); vis[ now ] = false; } } int main() { char from , to; int dist , m; while( ~scanf("%d",&n) ) { memset( head , -1 , sizeof(head) ); memset( vis , false , sizeof(vis) ); num = 0; scanf("%d",&m); getchar(); while( m-- ) { scanf( "%c %c %d" , &from , &to , &dist ); addedge( from-'A' , to-'A' , dist ); getchar(); } spfa(0); for( int i = 1 ; i<n ; i++ ) { printf("A %c " , 'A'+i ); if( dis[i] == inf ) { printf("No\n"); } else { printf("%d\n",dis[i]); } } } return 0; }
如果 你还有什么不明白的地方 小学妹们 快到 碗里来