PAT A1072 Gas Station(30)

题意

  • 这个题读起来有点烦,是这样的,首先有N个居民房和M个加油站,每个加油站都对应着一个最小距离和平均距离,加油站的最小距离是指从他到其他所有居民房的最短路径的最小值(从N条最短路径里面选),现在让你选择一个加油站,首先他到所有居民房的最短路径均不能大于服务范围(每个加油站都一样),其次他的最小距离在所有加油站的最小距离中最大(从M个加油站中选),若不唯一,选择平均距离最小的,若再不唯一,选择编号最小的。若没有一个加油站能服务到所有居民房,那么输出No Solution

注意

  1. 因为算每个加油站的最小距离和平均距离需要知道最短路径长度,所以每个加油站都要来一遍dijkstra,每算出来一个加油站到一个居民房的最短路径(S集新元素)就更新这个加油站的最小距离和平均距离,同时也要判断是否小等于服务范围,不然这个加油站的dijkstra直接结束。
  2. 把平均距离先按照距离和处理,最后再除。
  3. 把每个加油站的信息算完以后,再在加油站之间比这俩数,不满足服务范围的加油站不用考虑。
  4. 加油站编号还要处理一下。

代码

#include <iostream>
#include <algorithm>
#include <climits>
#include <string>  
using namespace std;

const int Nmax = 1011;
int N, M, K, Ds;
int road[Nmax][Nmax];

int dist[Nmax];
bool S[Nmax];

bool isM[11];
int minRoad[11];
int avgRoad[11];

void DIJKSTRA()
{
    fill(isM, isM + 11, false);
    fill(minRoad, minRoad + 11, INT_MAX);
    fill(avgRoad, avgRoad + 11, 0);
    for (int i = 1; i <= M; i++)
    {
        fill(S, S + Nmax, false);
        fill(dist, dist + Nmax, INT_MAX);
        dist[i + N] = 0;
        for (int k = 1; k <= N + M; k++)
        {
            int min = INT_MAX;
            int u;
            for (int j = 1; j <= N + M; j++)
            {
                if (!S[j] && dist[j] < min)
                {
                    min = dist[j];
                    u = j;
                }
            }
            if (dist[u] > Ds && u <= N)
            {
                isM[i] = true;                 //////
                break;
            }
            S[u] = true;
            if (u <= N)
            {
                avgRoad[i] += dist[u];
                if (dist[u] < minRoad[i])
                    minRoad[i] = dist[u];
            }
            for (int j = 1; j <= N + M; j++)
            {
                if (!S[j] && road[u][j] != INT_MAX)
                {
                    if (dist[u] + road[u][j] < dist[j])
                    {
                        dist[j] = dist[u] + road[u][j];
                    }
                }
            }
        }
    }
}

void select()
{
    int opt = 0;
    int max = -1;
    for (int i = 1; i <= M; i++)
    {
        if (!isM[i])
        {
            if (minRoad[i] > max)
            {
                max = minRoad[i];
                opt = i;
            }
            else if (minRoad[i] == max && avgRoad[i] < avgRoad[opt])
            {
                opt = i;
            }
        }
    }
    if (opt == 0)
    {
        cout << "No Solution";
        return;
    }
    double minR, avgR;
    minR = minRoad[opt];
    avgR = (double)(avgRoad[opt]) / (double)(N);
    cout << "G" << opt << endl;
    printf("%.1f %.1f", minR, avgR);
}

int main()
{
    cin >> N >> M >> K >> Ds;
    string r1, r2;
    int r3, r4;
    fill(road[0], road[0] + Nmax*Nmax, INT_MAX);
    for (int i = 0; i < K; i++)
    {
        cin >> r1 >> r2;
        if (r1[0] == 'G')
            r3 = atoi(r1.substr(1, r1.size() - 1).c_str()) + N;
        else
            r3 = atoi(r1.c_str());

        if (r2[0] == 'G')
            r4 = atoi(r2.substr(1, r2.size() - 1).c_str()) + N;
        else
            r4 = atoi(r2.c_str());

        cin >> road[r3][r4];
        road[r4][r3] = road[r3][r4];
    }
    DIJKSTRA();
    select();

    return 0;
}
posted @ 2017-02-10 19:50  CrossingOver  阅读(172)  评论(0编辑  收藏  举报