思路1:SLF优化spfa水过
#include <bits/stdc++.h>
using namespace std;
const int maxn = 25005;
const int maxm = 5000005;
const int inf = 0x3f3f3f3f;
int he[maxn],ver[maxm],ne[maxm],tot,cost[maxm];
void add( int x,int y,int z ){
ver[++tot] = y;
ne[tot] = he[x];
he[x] = tot;
cost[tot] = z;
}
int n,d[maxn],vis[maxn];
deque<int> que;
void spfa(int s){
memset( d,0x3f,sizeof(int)*(n+1) );
memset( vis,0,sizeof(int)*(n+1) );
d[s] = 0;vis[s] = 1;
que.push_back(s);
while(que.size()){
int x = que.front();
vis[x] = 0;
que.pop_front();
for( int cure = he[x];cure;cure = ne[cure] ){
int y = ver[cure];
if( d[y] > d[x] + cost[cure] ){
d[y] = d[x] + cost[cure];
if( !vis[y] ) {
if(que.size()&& d[y] < d[que.front()] )que.push_front(y);
else que.push_back(y);
vis[y] = 1;
}
}
}
}
}
int main(){
int r,p,s,x,y,z;
scanf("%d%d%d%d",&n,&r,&p,&s);
for( int i = 1;i <= r;i++ ){
scanf("%d%d%d",&x,&y,&z);
add( x,y,z );add( y,x,z );
}
for( int i = 1;i <= p;i++ ){
scanf("%d%d%d",&x,&y,&z);
add(x,y,z);
}
spfa(s);
for( int i = 1;i <= n;i++ ){
if( d[i] == inf ){
puts("NO PATH");
}
else printf("%d\n",d[i]);
}
return 0;
}
思路2:拓扑排序 + dijstra
#include <bits/stdc++.h>
using namespace std;
const int maxn = 250005;
const int maxm = 5000005;
const int inf = 0x7f7f7f7f;
int n,r,p,s;
int he[maxn],ver[maxm],ne[maxm],cost[maxm],tot;
int he2[maxn],ver2[maxm],ne2[maxm],tot2;
void add2( int x,int y ){
ver2[++tot2] = y;
ne2[tot2] = he2[x];
he2[x] = tot2;
}
void add( int x,int y,int z ){
ver[++tot] = y;
ne[tot] = he[x];
he[x] = tot;
cost[tot] = z;
}
vector<int> ve[maxn];
int du[maxn],vis[maxn],c[maxn];
void dfs( int x,int color ){
c[x] = color;
for( int cure = he[x];cure;cure = ne[cure] ){
int y = ver[cure];
if(c[y]) continue;
dfs(y,color);
}
}
int d[maxn];
void init( int s ){
memset( d,0x7f,sizeof(int)*(n+1) );
d[s] = 0;
}
typedef pair<int,int> pii;
priority_queue<pii,vector<pii>,greater<pii>> que;
void dijkstra(int color){
for( int i = 0;i < ve[color].size();i++ ){
que.push( pii( d[ve[color][i]],ve[color][i] ) );
}
while(que.size()){
int x = que.top().second;
que.pop();
for( int cure = he[x];cure;cure = ne[cure] ){
int y = ver[cure];
if( d[y] > d[x] + cost[cure] ){
d[y] = d[x] + cost[cure];
if( c[y] == c[x] )
que.push( pii(d[y],y) );
}
}
}
}
queue<int> Q;
int main(){
scanf("%d%d%d%d",&n,&r,&p,&s);
init(s);
int x,y,z,color = 0;
for( int i = 1;i <= r;i++ ){
scanf("%d%d%d",&x,&y,&z);
add(x,y,z);add(y,x,z);
}
for( int i = 1;i <= n;i++ ){
if( !c[i] )
dfs(i,++color);
}
memset( vis,0,sizeof(int)*(n+1) );
for( int i = 1;i <= n;i++ ){
ve[ c[i] ].push_back(i);
}
for( int i = 1;i <= p;i++ ){
scanf("%d%d%d",&x,&y,&z);
add( x,y,z );
add2( c[x],c[y] );
du[c[y]]++;
}
for( int i = 1; i <= color;i++ ){
if( !du[i] ) {
Q.push(i);
dijkstra(i);
}
}
while(Q.size()){
int x = Q.front();
Q.pop();
for( int cure = he2[x];cure;cure = ne2[cure] ){
int y = ver2[cure];
du[y]--;
if(!du[y]){
Q.push(y);
dijkstra(y);
}
}
}
for( int i = 1; i <= n;i++ ){
if( d[i]>=0x3f3f3f3f ) puts("NO PATH");
else printf("%d\n",d[i]);
}
return 0;
}