既然卡SPFA,那就用Dijkstra + 堆优化
我太菜了就不会SPFA
就是要注意,可能有些同学会说:
“我们又不是不会Dijkstra + 堆优化”
于是自信满满的交上,一看就傻眼了,,,
60分?! #2 #3 TLE?!
这里就是一个需要注意的地方了
过不去可能是因为没有加一个简单的优化:(下面截取一部分代码)
while (q.size()){
int u = q.top().v;
int d = q.top().u;
q.pop();
if(d!=dis[u])//这里是优化哦
continue;//QAQ
rep(i,u){
int v = e[i].v;
int w = e[i].w;
if (dis[v] > dis[u] + w){
dis[v] = dis[u] + w;
node p;
p.u = dis[v], p.v = v;
q.push(p);
}
}
}
这个优化把一些不可行的路径直接跳过去,会减少一些时间
没有这句是2500+ms
有这句只需208msQAQ
那么Dijkstra是不需要讲的(如果你做过弱化版)
堆优化似乎也不难,就是拿堆优化找最短dis就好
完整代码:
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>
using namespace std;
#define go(i, j, n, k) for (int i = j; i <= n; i += k)
#define fo(i, j, n, k) for (int i = j; i >= n; i -= k)
#define rep(i, x) for (int i = h[x]; i; i = e[i].nxt)
#define mn 100010
#define inf 1 << 30
#define ll long long
#define ld long double
#define fi first
#define se second
#define root 1, n, 1
#define lson l, m, rt << 1
#define rson m + 1, r, rt << 1 | 1
inline int read(){
int f = 1, x = 0;char ch = getchar();
while (ch > '9' || ch < '0'){if (ch == '-')f = -f;ch = getchar();}
while (ch >= '0' && ch <= '9'){x = x * 10 + ch - '0';ch = getchar();}
return x * f;
}
inline void write(int x){
if (x < 0)putchar('-');x = -x;
if (x > 9)write(x / 10);
putchar(x % 10 + '0');
}
//This is AC head above...
struct edge{
int v, nxt, w;
} e[mn<<1];
int h[mn],p;
inline void add(int a,int b,int c){
p++;
e[p].nxt = h[a];
h[a] = p;
e[p].v = b;
e[p].w = c;
}
struct node{
int u,v;
bool operator <(const node &b) const{
return u > b.u;
}
};
/*
bool operator <(const node &a,const node &b) {
return a.u > b.u;
};
*/
int n,m,s;
int dis[mn];
priority_queue<node> q;
inline void Dij(int s){
go(i, 0, n, 1)
dis[i] = inf;
dis[s] = 0;
node o;
o.u = 0;
o.v = s;
q.push(o);
while (q.size()){
int u = q.top().v;
int d = q.top().u;
q.pop();
if(d!=dis[u])
continue;
rep(i,u){
int v = e[i].v;
int w = e[i].w;
if (dis[v] > dis[u] + w){
dis[v] = dis[u] + w;
node p;
p.u = dis[v], p.v = v;
q.push(p);
}
}
}
}
int main(){
n=read(),m=read(),s=read();
go(i,1,m,1){
int u = read(), v = read(), w = read();
add(u, v, w);
}
Dij(s);
go(i,1,n,1){
cout << dis[i] << " ";
}
cout << "
";
return 0;
}