PAT A1072 Gas Station

思路:注意首先加油站必须满足到达所有房屋的距离不超过Ds,在此基础上,要使最近的距离最大。

当出现多个最近距离最大的解的时候,选择平均距离最小的解,优先选择索引更小的位置。使用M次Dijkstra算法将M个加油站位置全部遍历一遍可得到答案。

#include<iostream>
#include<algorithm>
#include<vector>
#include<cstdio>
using namespace std;

const int MAXN = 1015;
const int INF = 1e9;

int N, M, K, Ds;
int G[MAXN][MAXN], d[MAXN];
bool visit[MAXN];
int ansGas = -1;
double ansDist = -1, ansAvg = INF;

int transform(string s) {
    if(s[0] != 'G') return stoi(s);
    return stoi(s.substr(1)) + N;
}

void Dijkstra(int s) {
    fill(d, d + MAXN, INF);
    fill(visit, visit + MAXN, false);
    d[s] = 0;
    for(int i = 0; i < N + M; i++) {
        int u = -1, MIN = INF;
        for(int j = 1; j <= N + M; j++)
            if(!visit[j] && d[j] < MIN) {
                u = j;
                MIN = d[j];
            }
        if(u == -1) return;
        visit[u] = true;
        for(int v = 1; v <= N + M; v++)
            if(!visit[v] && d[u] + G[u][v] < d[v]) 
                d[v] = d[u] + G[u][v];
    }
}

int main() {
    cin >> N >> M >> K >> Ds;
    string p1, p2;
    int id1, id2, dist;
    fill(G[0], G[0] + MAXN * MAXN, INF);
    for(int i = 0; i < K; i++) {
        cin >> p1 >> p2 >> dist;
        id1 = transform(p1);
        id2 = transform(p2);
        G[id1][id2] = G[id2][id1] = dist;
    }
    double avg, minDist;
    for(int i = N + 1; i <= N + M; i++) {
        Dijkstra(i);
        minDist = INF, avg = 0;
        for(int j = 1; j <= N; j++) {
            if(d[j] > Ds) {
                minDist = -1;
                break;
            }
            if(d[j] < minDist) minDist = d[j];
            avg += d[j];
        }    
        avg /= N;
        if(minDist == -1) continue;
        if(minDist > ansDist) {
            ansDist = minDist;
            ansGas = i;
            ansAvg = avg;
        } else if(minDist == ansDist && avg < ansAvg) {
            ansGas = i;
            ansAvg = avg;
        }
    }
    if(ansGas == -1) cout << "No Solution" << endl;
    else {
        cout << "G" << ansGas - N << endl;
        printf("%.1f %.1f\n", ansDist, ansAvg);
    }
    return 0;
}