SPFA板子(前向星)
1 #include <bits/stdc++.h> 2 3 using namespace std; 4 const int INF = 0x3f3f3f3f; 5 6 struct node 7 { 8 int v, w, next; 9 }edge[5000005]; 10 int n, tot; 11 int head[1000005], dis[1000005]; 12 bool vis[1000005]; 13 14 void add_edge(int u,int v,int w) 15 { 16 tot++; 17 edge[tot].v = v; 18 edge[tot].w = w; 19 edge[tot].next = head[u]; 20 head[u]=tot; 21 } 22 23 void spfa(int x) 24 { 25 queue <int> q; 26 for(int i=1;i<=n;i++) 27 { 28 dis[i] = INF; 29 vis[i] = 0; 30 } 31 dis[x] = 0; 32 vis[x] = 1; 33 q.push(x); 34 while(!q.empty()) 35 { 36 int u = q.front(); 37 q.pop(); 38 vis[u] = 0; 39 for(int i=head[u]; i; i=edge[i].next) 40 { 41 int v = edge[i].v; 42 if(dis[v] > dis[u]+edge[i].w) 43 { 44 dis[v] = dis[u]+edge[i].w; 45 if(!vis[v]) 46 { 47 vis[v] = 1; 48 q.push(v); 49 } 50 } 51 } 52 } 53 } 54 55 int main() 56 { 57 int m; 58 ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); 59 cin >> n >> m; 60 tot = 0; 61 while(m--) 62 { 63 int u, v; 64 cin >> u >> v; 65 add_edge(u, v, 1); 66 add_edge(v, u, 1); 67 } 68 spfa(1); 69 for(int i=1; i<=n; i++) 70 { 71 cout << i << " " << dis[i] << endl; 72 } 73 return 0; 74 }
类比bfs,不同之处在于在队列中出现过的点允许再次出现,直至队列为空。
SPFA:动态逼近法