【题意】: 给定 n n n个点和 m m m条边,求起点 s s s到所有点的最短路。
【思路】: 两道题的题意一模一样,但由于数据范围的差异和数据的来源,两题的解法稍有不同,考察了求最短路最经典而快速的两种方法: s p f a spfa spfa算法和带堆优化的 d i j k s t r a dijkstra dijkstra算法(注意“带堆优化”这几个字眼,不带堆优化的 d i j k s t r a dijkstra dijkstra时间复杂度为 O ( n 2 ) O(n^2) O(n2),而带堆优化的 d i j k s t r a dijkstra dijkstra时间复杂度仅为 O ( n × l o g n ) O(n\times logn) O(n×logn))。
在这里,个人推荐在无负边权时用 d i j k s t r a dijkstra dijkstra算法,其它情况用 s p f a spfa spfa算法,甚至在一般情况下都可以用 s p f a spfa spfa算法。
【代码】:
[code of the algorithm spfa(即P3371题题解)]:
//By HPXXZYY
#include
using namespace std;
const int M=500100;
const int N=100100;
struct node{
int next,to,w;
}e[M];int h[N],tot;
inline void add_edge(int a,int b,int c){
e[++tot]=(node){h[a],b,c};h[a]=tot;
}
long long d[N];bool vis[N];
void spfa_algorithm(int s){
queue<int> q;q.push(s);
memset(vis,true,sizeof(vis));
memset(d,127,sizeof(d));
d[s]=vis[s]=0;
do{
int u=q.front();q.pop();vis[u]=true;
for(int i=h[u];i;i=e[i].next){
register int v=e[i].to;
if (d[v]>d[u]+e[i].w){
d[v]=d[u]+e[i].w;
if (vis[v]){
vis[v]=false;
q.push(v);
}
}
}
}while (q.size());
}
#define gc getchar()
#define g(c) isdigit(c)
inline int read(){
char c=0;int x=0;bool f=0;
while (!g(c)) f=c=='-',c=gc;
while (g(c)) x=x*10+c-48,c=gc;
return f?-x:x;
}
int n,m,a,b,i,s;
int main(){
freopen("t1.in","r",stdin);
n=read();m=read();s=read();
for(i=1;i<=m;i++){
a=read();b=read();
add_edge(a,b,read());
}
spfa_algorithm(s);
for(i=1;i<=n;i++)
if (d[i]!=d[0]) printf("%d ",d[i]);
else printf("2147483647 ");
return 0;
}
[code of the algorithm dijkstra(即P4779题题解)]:
//By HPXXZYY,too.
#include
using namespace std;
const int M=200100;
const int N=100100;
struct node{
int next,to,w;
}e[M];int h[N],tot;
inline void add_edge(int a,int b,int c){
e[++tot]=(node){h[a],b,c};h[a]=tot;
}
struct data{
int u,len;
bool operator < (data c) const{
return len>c.len;
}
};
int d[N];
void dijkstra(int s){
priority_queue<data> q;
q.push((data){s,0});
// memset(vis,true,sizeof(vis));
memset(d,127,sizeof(d));
d[s]=/*vis[s]=*/false;
while (q.size()){
data z=q.top();q.pop();
int u=z.u,len=z.len;
if (len!=d[u]) continue;
for(int i=h[u];i;i=e[i].next){
register int v=e[i].to;
if (d[v]>d[u]+e[i].w){
d[v]=d[u]+e[i].w;
q.push((data){v,d[v]});
}
}
}
}
#define gc getchar()
#define g(c) isdigit(c)
inline int read(){
char c=0;int x=0;bool f=0;
while (!g(c)) f=c=='-',c=gc;
while (g(c)) x=x*10+c-48,c=gc;
return f?-x:x;
}
int n,m,a,b,i,s;
int main(){
freopen("t1.in","r",stdin);
n=read();m=read();s=read();
for(i=1;i<=m;i++){
a=read();b=read();
add_edge(a,b,read());
}
dijkstra(s);
for(i=1;i<=n;i++)
printf("%d ",d[i]);
return 0;
}