zoukankan      html  css  js  c++  java
  • PAT甲题题解-1072. Gas Station (30)-dijkstra最短路

    题意:从m个加油站里面选取1个站点,使得其离住宅的最近距离mindis尽可能地远,并且离所有住宅的距离都在服务范围ds之内。
    如果有很多相同mindis的加油站,输出距所有住宅平均距离最小的那个。
    如果平均值还是一样,就输出按照顺序排列加油站编号最小的。

    分析:
    加油站之间也是彼此有路连接的,所以最短路径计算的时候也要把加油站算上,是双向边,所以边的数组大小得开两倍。
    加油站编号记为n+1~n+m,对这些点用dijkstra计算最短路径即可,这里顺便在dijkstra中进行了剪枝处理,不剪枝也没事。

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <string.h>
    #include <queue>
    #define INF 0X3f3f3f3f
    using namespace std;
    /*
    从m个加油站里面选取1个站点,使得其离住宅的最近距离mindis尽可能地远,并且离所有住宅的距离都在服务范围ds之内。
    如果有很多相同mindis的加油站,输出距所有住宅平均距离最小的那个。
    如果平均值还是一样,就输出按照顺序排列加油站编号最小的。
    分析:
    加油站之间也是彼此有路连接的,所以最短路径计算的时候也要把加油站算上,是双向边,所以边的数组大小得开两倍。
    加油站编号记为n+1~n+m,对这些点用dijkstra计算最短路径即可,这里顺便在dijkstra中进行了剪枝处理,不剪枝也没事。
    */
    const int maxn=1000+15;
    int dis[maxn];
    int vis[maxn];
    int head[maxn];
    int tot=0;
    int mindis;
    struct Node{
        int u;
        int dis;
        bool operator<(const Node tmp)const{
            return dis>tmp.dis;
        }
    };
    
    struct Edge{
        int to;
        int next;
        int dist;
    }edge[10005*2];
    
    void add(int u,int v,int dist){
        edge[tot].to=v;
        edge[tot].dist=dist;
        edge[tot].next=head[u];
        head[u]=tot++;
    }
    void init(){
        memset(head,-1,sizeof(head));
        tot=0;
    }
    bool dijkstra(int s,int n){
        for(int i=0;i<maxn;i++){
            dis[i]=INF;
            vis[i]=0;
        }
        priority_queue<Node>q;
        Node st,t;
        st.u=s;
        st.dis=0;
        dis[s]=0;
        q.push(st);
        bool first=true;
        while(!q.empty()){
            st=q.top();
            q.pop();
            vis[st.u]=1;
            if(first && 1<=st.u && st.u<=n){
                if(dis[st.u]<mindis){
                    return false; //剪枝,即离车站最小的距离比目前的mindis还要小,直接返回即可
                }
                first=false;
            }
            for(int k=head[st.u];k!=-1;k=edge[k].next){
                int v=edge[k].to;
                if(!vis[v] && dis[st.u]+edge[k].dist<dis[v]){
                    dis[v]=dis[st.u]+edge[k].dist;
                    t.u=v;
                    t.dis=dis[v];
                    q.push(t);
                }
            }
        }
        return true;
    }
    int main()
    {
        int n,m,k,ds;
        char str1[10],str2[10];
        int u,v,dist;
        scanf("%d %d %d %d",&n,&m,&k,&ds);
        init();
        for(int i=0;i<k;i++){
            scanf("%s %s %d",str1,str2,&dist);
            if(str1[0]=='G')
                u=atoi(str1+1)+n;
            else
                u=atoi(str1);
            if(str2[0]=='G')
                v=atoi(str2+1)+n;
            else
                v=atoi(str2);
            add(u,v,dist);
            add(v,u,dist);
        }
        mindis=0;
        double avgdis=INF;
        int gasid=0;
        bool noAns=true;
        for(int i=1;i<=m;i++){
            //如果最小距离小于目前的mindis,直接跳过
            if(!dijkstra(n+i,n)){
                continue;
            }
            dist=INF;
            int sum=0;
            bool flag=true;
            for(int j=1;j<=n;j++){
                //有超出服务范围的
                if(dis[j]>ds){
                    flag=false;
                    break;
                }
                dist=min(dist,dis[j]);
                sum+=dis[j];
            }
            if(!flag)
                continue;
            else
                noAns=false;
            double avg=sum*1.0/n;
            if(dist>mindis){
                gasid=i;
                mindis=dist;
                avgdis=avg;
            }
            else if(dist==mindis){
                if(avg<avgdis){
                    gasid=i;
                    avgdis=avg;
                }
            }
        }
        if(noAns)
            printf("No Solution
    ");
        else
            printf("G%d
    %.1lf %.1lf
    ",gasid,(double)mindis,avgdis);
        return 0;
    }
    View Code
  • 相关阅读:
    几种排序方法详解(选择排序、冒泡排序、插入排序、快速排序)
    几种排序方法详解(选择排序、冒泡排序、插入排序、快速排序)
    Cookie
    ajax
    layer弹出框
    Session
    Cookie
    顺时针打印矩阵
    常用判断
    基础学习
  • 原文地址:https://www.cnblogs.com/chenxiwenruo/p/6390676.html
Copyright © 2011-2022 走看看