spfa 就是加了一个剪枝(忽略了不需要考虑的节点)
1.起点加入队列 O(1)
2.取队列中距离起点最近的点i O(1) or O(1) = O(1)
2.1判断i是否为终点 如果是 结束 O(1)
2.2判断i是否值得进一步计算(当前i到起点距离是已知i到起点距离中最小的) O(1) or O(1) = O(1)
2.2.1如果不值得 返回2 O(1)
2.2.2如果值得 记录当前距离为最小距离并继续 O(1)
3.遍历i的相邻节点j。 O(m/n)
3.1判断j是否值得加入队列(当前j到起点距离是已知j到起点距离中最小的) O(log(len(prority_queue)))
3.1.1如果不值得,继续3的遍历 O(1)
3.1.2如果值得加入队列 记录当前距离为最小距离并继续 O(log(len(prority_queue)))
4返回2;
2~3最多执行n次
这不是dijstra+剪枝吗?
难道写错了?
#include<iostream> #include<vector> #include<algorithm> #include<cstring> #include<queue> using namespace std; const int max_point = 100100; struct Node { int target; int dist; }node,node_t; struct cmp { bool operator ()(Node n1,Node other) { return n1.dist>other.dist; } }; vector<Node> edge[max_point]; int dis[max_point]; int main() { priority_queue<Node,vector<Node>,cmp> pri_que; int n,m,s,t; cin>>n>>m>>s>>t; s--,t--; memset(dis,0x0f,sizeof(dis)); int v,u,d; for(int i=0;i<m;i++) { cin>>v>>u>>d; v--,u--; node.target = u; node.dist = d; edge[v].push_back(node); node.target=v; edge[u].push_back(node); } node.target = s; node.dist = 0; pri_que.push(node); while(true) { node = pri_que.top(); pri_que.pop(); if(dis[node.target]<node.dist) {continue;} else dis[node.target] = node.dist; if(node.target == t) { break; } for(int i=0;i<edge[node.target].size();i++) { int next_tar = edge[node.target][i].target; int next_dis = edge[node.target][i].dist; int new_dis = next_dis+node.dist; if(new_dis>dis[next_tar]) continue; else{ node_t.target = next_tar; node_t.dist = new_dis; dis[next_tar]=new_dis; pri_que.push(node_t); } } } cout<<dis[t]<<endl; return 0; }