道路和航线
道路和航线
https://ac.nowcoder.com/acm/problem/50381
分析
本题给出的道路和航线其实就是单向道路和双向道路
所以我们直接正常建边就可了
由于题目保证了不存在环,那么就绝对没有负环情况
但因为有负边,所以我们需要用SPFA
所以我们直接套板子即可
当然,这里我们使用SPFA的优化(slf优化 或者 lll优化)
(机房大佬说想要不一样就要Tarjan缩点+Dijkstra)
代码
//LOJ 10081 #include <iostream> #include <cstdio> #include <algorithm> #include <deque> #include <cmath> #include <cstring> #define LL long long #define Lowbit(X) (X&(-X)) #define Lson (X<<1) #define Rson (X<<1|1) #define Cl(X,Y) memset((X),(Y),sizeof(X)) #define FOR(i,A,B) for(int i=A;i<=B;i++) #define BOR(i,A,B) for(int i=A;i>=B;i--) #define FOR_SIDE(i,A) for(int i=Head[A];i;i=Next[i]) #define INF 0x3f3f3f3f using namespace std; const int MaxN=1e5+10; int Sta,Total,Side,R,P; int u,v,w,Opt,Dist[MaxN]; bool Vis[MaxN]; int Next[MaxN<<1],End[MaxN<<1],Cur,Head[MaxN],Val[MaxN<<1]; deque<int>Temp; inline void File() { freopen(".in","r",stdin); freopen(".out","w",stdout); } inline void Add_Edge(int From,int To,int Temp) { Next[++Cur]=Head[From]; Head[From]=Cur; End[Cur]=To; Val[Cur]=Temp; } inline void SPFA() { Cl(Dist,0x3f); Dist[Sta]=0; Vis[Sta]=true; Temp.push_front(Sta); while(!Temp.empty()) { int New=Temp.front(); Temp.pop_front(); Vis[New]=false; FOR_SIDE(i,New) { if(Dist[End[i]]>Dist[New]+Val[i]) { Dist[End[i]]=Dist[New]+Val[i]; if(!Vis[End[i]]) { if(Temp.empty() || Dist[End[i]]<Dist[Temp.front()]) Temp.push_front(End[i]); else Temp.push_back(End[i]); Vis[End[i]]=true; } } } } } int main() { //File(); scanf("%d %d %d %d",&Total,&R,&P,&Sta); Side=R+P; FOR(i,1,R) { scanf("%d %d %d",&u,&v,&w); Add_Edge(u,v,w); Add_Edge(v,u,w); } FOR(i,1,P) { scanf("%d %d %d",&u,&v,&w); Add_Edge(u,v,w); } SPFA(); FOR(i,1,Total) { if(Dist[i]==INF) { printf("NO PATH\n"); } else { printf("%d\n",Dist[i]); } } //fclose(stdin); fclose(stdout); system("pause"); return 0; }