Dij
#include<bits/stdc++.h>
using namespace std;
typedef pair<long long,int> P; //
const int N = 2e5+100;
int a[N],n,m,k,t;
int Head[N],Next[N*2],To[N*2],cnt = 0,val[N*2];
long long dis[N];
bool vis[N];
priority_queue<P,vector<P>, greater<P> > q; //小根堆。
void add(int u, int v, int w){
++cnt;
Next[cnt] = Head[u];
To[cnt] = v;
val[cnt] = w;
Head[u] = cnt;
}
void dij(){
for (int i = 0; i <= n; ++i) dis[i] = 1e13;
dis[1] = 0; q.push(P(0,1));
while(!q.empty()){
int u = q.top().second; //找到dis 最小的起点。
q.pop();
if (vis[u]) continue;
vis[u] = 1; //这个起点已经更新过了。
for (int i = Head[u]; i; i = Next[i]){ // 更新之后的点。
int v = To[i];
long long w = val[i];
if (a[v] > t) w += 1ll*(a[v]-t)*(a[v]-t); //这个是另外加的权值。
if (dis[v] > dis[u] + w){
dis[v] = dis[u] + w;
q.push(P(dis[v],v));
}
}
}
return;
}
int main(){
int x,y,z;
scanf("%d%d%d",&n,&m,&k);
for (int i = 1; i <= n; ++i) scanf("%d",&a[i]);
for (int i = 0; i < m; ++i){
scanf("%d%d%d",&x,&y,&z);
add(x,y,z); add(y,x,z);
}
t = a[1] + k; //判断能够达到最高的山高。
dij();
printf("%lld\n",dis[n]);
return 0;
}
Tarjan + SPFA
#include<bits/stdc++.h>
using namespace std;
const int N = 5e5+1000;
int Head[N],Next[N],To[N],Val[N],cnt;
int n,m,S,p;
bool vis[N];
void add(int u, int v){
Next[++cnt] = Head[u];
Head[u] = cnt;
To[cnt] = v;
}
void init(){
int x,y;
scanf("%d%d",&n,&m);
for (int i = 0; i < m; ++i){
scanf("%d%d",&x,&y);
add(x,y);
}
for (int i = 1; i <= n; ++i)
scanf("%d",&Val[i]);
scanf("%d%d",&S,&p);
for (int i = 0;i < p; ++i)
scanf("%d",&x),vis[x] = 1;
}
stack<int>q;
int low[N],dfn[N],tim,scc[N],cont;
void Tarjan(int u){
low[u] = dfn[u] = ++tim;
q.push(u);
for (int i = Head[u]; i; i = Next[i]){
int v = To[i];
if (!dfn[v]){
Tarjan(v);
low[u] = min(low[u],low[v]);
} else if (!scc[v]) low[u] = min(low[u],dfn[v]);
}
if (low[u] == dfn[u]){
cont++;
while(1){
int v = q.top(); q.pop();
scc[v] = cont;
if (v == u) break;
}
}
}
vector<int>f[N];
int val[N],dis[N];
bool dep[N];
void spfa(int u){
queue<int>Q;
Q.push(u); dis[u] = val[u]; dep[u] = 1;
while(!Q.empty()){
int u = Q.front(); Q.pop(); dep[u] = 0;
int ss = f[u].size();
for (int i = 0; i < ss; ++i){
int v = f[u][i];
if (dis[v] < dis[u] + val[v]){
dis[v] = dis[u] + val[v];
if (dep[v] == 0){
dep[v] = 1;
Q.push(v);
}
}
}
}
}
int main(){
init();
Tarjan(S);
int u,v;
for (int i = 1; i <= n; ++i){
u = scc[i];
val[u] += Val[i];
for (int j = Head[i]; j; j = Next[j]){
v = scc[To[j]];
if (v != u) f[u].push_back(v);
}
}
spfa(scc[S]);
int ans = 0;
for (int i = 1; i <= n;++i)
if (vis[i]) ans = max(ans,dis[scc[i]]);
printf("%d\n",ans);
return 0;
}