• UVA 10246 Asterix and Obelix


    题意:每个城市举办庆祝有一定的花费,A在路径上会选择庆祝花费最大的城市      

       让你求,A回家所花的路费和庆祝费最少,也就是说并不是最短路径就是结果,      

       还有可能就是路费比最短路径的多,但是庆祝费就比它的少,总的加起来可能更小。

    思路:枚举每个城市作为庆祝的点,设为x。以x为源点,用dijks求单源路径,路径上如果有大于x庆祝费的点,则不考虑进去。      

        求完所有点到x的单源路径后,用两重j、k的for循环,同步更新从j到k所需要的最小花费

    #include <iostream>
    #include <algorithm>
    #include <string.h>
    #include <string>
    #include <cstring>
    #include <stdio.h>
    #include <map>
    #include <vector>
    using namespace std;
    const int maxn=0x3f3f3f3f;
    
    int c,r,q;
    int c1,c2,d;
    int a,b;
    int road[101][101];
    int feast[101];
    int ans[81][81];//ans[i][j]即为询问的答案,表示i到j最少的花费
    int dis[81];//当x为庆祝点时,dis[i]表示以第x城市作为举办宴会的地方,i到x之间的最短路径(即花费);
    vector<int> link[101];
    int vis[81];
    int cases=0;
    int blank=0;
    
    void init(){
        for(int i=0;i<=c;i++)
            link[i].clear();
        memset(road,maxn,sizeof(road));
        memset(ans,maxn,sizeof(ans));
    }
    int main()
    {
        while(scanf("%d%d%d",&c,&r,&q)!=EOF){
            if(c==0 && r==0 && q==0)
                break;
            //如果不这样,则最后一个case输出完后会多打一个空格,这也给我wrong answer。。。
            if(blank)
                puts("");
            else
                blank=1;
            cases++;
            init();
            for(int i=1;i<=c;i++){
                scanf("%d",&feast[i]);
            }
            for(int i=0;i<r;i++){
                scanf("%d%d%d",&c1,&c2,&d);
                road[c1][c2]=d;
                road[c2][c1]=d;
                link[c1].push_back(c2);
                link[c2].push_back(c1);
            }
    
            for(int i=1;i<=c;i++){
    
                //以i作为庆祝城市,并且以i作为源点,求单源路径
                memset(dis,maxn,sizeof(dis));
                dis[i]=0;
                memset(vis,0,sizeof(vis));
    
                //循环n次,这里我没用优先级队列
                for(int z=1;z<=c;z++){
                    int mincost=maxn;
                    int idx;
                    for(int k=1;k<=c;k++){
                        if(vis[k]==0){
                            if(dis[k]<mincost && feast[k]<=feast[i]){
                                mincost=dis[k];
                                idx=k;
                            }
                        }
                    }
                    vis[idx]=1;
                    for(int g=0;g<link[idx].size();g++){
                        int v=link[idx][g];
                        if(v!=idx){
                            if(feast[v]<=feast[i] && dis[idx]+road[idx][v]<dis[v]){
                                dis[v]=dis[idx]+road[idx][v];
                            }
                        }
                    }
                }
               
               //每次求完以i为庆祝点的单源路径后,与之前比较,更新ans[j][k]的值,
            //如果此次,从j到k之间在i点庆祝的花费比之前一次循环中的在i'庆祝的花费要少,则更新
                for(int j=1;j<=c;j++){
                    for(int k=1;k<=c;k++){
                        if(feast[i]+dis[j]+dis[k]<ans[j][k]){
                            ans[j][k]=feast[i]+dis[j]+dis[k];
                        }
                    }
                }
    
            }
            printf("Case #%d
    ",cases);
            for(int i=1;i<=q;i++){
                scanf("%d%d",&a,&b);
                if(ans[a][b]==maxn){
                    printf("-1
    ");
                }
                else{
                    printf("%d
    ",ans[a][b]);
                }
            }
            //printf("
    ");
    
        }
        return 0;
    }
  • 相关阅读:
    fedora 安装open office
    git rebase(转)
    javascript typeof
    正则表达式入门
    XML格式
    zz 通用线程:Awk 实例,第 3部分
    ELF BIN HEX
    i2c总线(iic总线/ I square C)
    grep
    把Nginx注册成Windows 系统服务(转载)
  • 原文地址:https://www.cnblogs.com/chenxiwenruo/p/3280551.html
Copyright © 2020-2023  润新知