P2966 牛收费路径
题面:https://www.luogu.org/problemnew/show/P2966
本题直接枚举过路草地收费最大点,然后跑n遍dijkstra即可。
Code:
#include<bits/stdc++.h>
using namespace std;
const int N=255;
int n,m,q,p[N],map[N][N],dist[N],ans[N][N],vis[N];
void dijkstra(int k){
memset(vis,0,sizeof(vis));
memset(dist,0x3f,sizeof(dist));
dist[k]=0;
for(int i=1;i<=n;i++){
int v=-1;
for(int u=1;u<=n;u++){
if(((dist[u]<dist[v])||(v==-1))&&(p[u]<=p[k])&&(!vis[u])){
v=u;
}
if(v==-1){
break;
}
vis[v]=true;
for(int u=1;u<=n;u++){
if(p[u]>p[k]){
continue;
}
dist[u]=min(dist[u],dist[v]+map[v][u]);
}
}
}
}
int main(){
int u,v,w,a,b;
memset(ans,0x3f,sizeof(ans));
scanf("%d%d%d",&n,&m,&q);
for(int i=1;i<=n;i++){
scanf("%d",&p[i]);
}
for(int i=1;i<=m;i++){
scanf("%d%d%d",&u,&v,&w);
map[u][v]=map[v][u]=min(map[u][v],w);
}
for(int k=1;k<=n;k++){
dijkstra(k);
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
ans[i][j]=min(ans[i][j],dist[i]+dist[j]+p[k]);
}
}
}
for(int i=1;i<=q;i++){
scanf("%d%d",&a,&b);
printf("%d\n",ans[a][b]);
}
return 0;
}