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;
}
posted @ 2019-07-16 15:01  prestige  阅读(89)  评论(0编辑  收藏  举报