uva10246- Asterix and Obelix

题目大意及思路:

一个人从某个城市去另一个城市,在途经的某个城市(包括起点和终点)要请人吃饭,在每个城市吃饭的花费不同,在每个城市间行走所需费用也不同。现在他在旅途中吃饭最贵的城市请人吃饭,问总的花费最小是多少。

Sample Input

 

7 8 5

2 3 5 15 4 4 6

1 2 20

1 4 20

1 5 50

2 3 10

3 4 10

3 5 10

4 5 15

6 7 10

1 5

 

比如这组样例 :从1到5花费最小的路径是1-2-3-5=20+10+10+ 5(1 2 3 5中吃饭最贵的城市为3,花5块钱)=45

解法:很明显的最短路径,但现在多了一个“要吃饭”的点要考虑,我们可以枚举吃饭的点,并求出每个点到吃饭点的距离,这里要注意,必须保证这条路上所有点的点权不得大于吃饭点的权值。最后按照询问的点直接计算即可

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <queue>
#define INF 999999999
using namespace std;
int host[100],g[100][100],vis[100],dis[100][100],crt[100];
void readcase(int r,int c){
    for(int i=1;i<=r;i++){
        scanf("%d",&host[i]);
    }
    for(int i=1;i<=c;i++){
        int x,y,z;
        scanf("%d%d%d",&x,&y,&z);
        g[x][y]=z;
        g[y][x]=z;
    }
}
int spfa(int s,int r){
    memset(vis,0,sizeof(vis));
    queue<int>que;
    while(!que.empty()){
        que.pop();
    }
    que.push(s);
    vis[s]=1;
    dis[s][s]=0;
    while(!que.empty()){
        int now=que.front();
        que.pop();
        vis[now]=0;
        for(int i=1;i<=r;i++){
            if(g[now][i] <INF&&dis[s][i]>dis[s][now]+g[now][i] && host[now]<=host[s] && host[i] <= host[s] ){
                dis[s][i]=dis[s][now]+g[now][i];
                if(vis[i]==0){
                    vis[i]=1;
                    que.push(i);
                }
            }
        }
    }
}
void compute(int r,int q,int c){
    for(int i=1;i<=q;i++){
        int s,t;
        scanf("%d%d",&s,&t);
        int ans=INF;
        for(int i=1;i<=r;i++){
            //cout<<dis[i][s]<<" "<<dis[i][t]<<endl;
            if(ans>dis[i][s]+dis[i][t]+host[i]){
                ans=dis[i][s]+dis[i][t]+host[i];
            }
            //cout<<ans<<endl;
        }
        if(ans<INF){
            printf("%d\n",ans);
        }
        else{
            printf("-1\n");
        }
    }
}
int main()
{
    int r,c,q;
    int counter=0;
    while(~scanf("%d%d%d",&r,&c,&q) && (r!=0 || c!=0 || q!=0)){
        if(counter!=0){
            printf("\n");
        }
        counter++;
        printf("Case #%d\n",counter);
        memset(host,0,sizeof(host));
        for(int i=1;i<=r;i++){
            for(int j=1;j<=r;j++){
                g[i][j]=INF;
            }
        }
         for(int i=1;i<=r;i++){
        for(int j=1;j<=r;j++){
            dis[i][j]=INF;
        }
        }
        readcase(r,c);
        for(int i=1;i<=r;i++){
            spfa(i,r);
            //cout<<endl;
        }
        compute(r,q,c);
    }
    return 0;
}


 

posted @ 2015-01-12 19:00  Scale_the_heights  阅读(193)  评论(0编辑  收藏  举报