垃圾箱分佈

貓的玖月發表於2020-10-22

大家倒垃圾的時候,都希望垃圾箱距離自己比較近,但是誰都不願意守著垃圾箱住。所以垃圾箱的位置必須選在到所有居民點的最短距離最長的地方,同時還要保證每個居民點都在距離它一個不太遠的範圍內。

現給定一個居民區的地圖,以及若干垃圾箱的候選地點,請你推薦最合適的地點。如果解不唯一,則輸出到所有居民點的平均距離最短的那個解。如果這樣的解還是不唯一,則輸出編號最小的地點。

輸入格式:
輸入第一行給出4個正整數:N(≤10​3)是居民點的個數;M(≤10)是垃圾箱候選地點的個數;K(≤10​4 )是居民點和垃圾箱候選地點之間的道路條數;DS是居民點與垃圾箱之間不能超過的最大距離。所有的居民點從1到N編號,所有的垃圾箱候選地點從G1到GM編號。

隨後K行,每行按下列格式描述一條道路:

P1 P2 Dist
其中P1和P2是道路兩端點的編號,端點可以是居民點,也可以是垃圾箱候選點。Dist是道路的長度,是一個正整數。

輸出格式:
首先在第一行輸出最佳候選地點的編號。然後在第二行輸出該地點到所有居民點的最小距離和平均距離。數字間以空格分隔,保留小數點後1位。如果解不存在,則輸出No Solution。

輸入樣例1:
4 3 11 5
1 2 2
1 4 2
1 G1 4
1 G2 3
2 3 2
2 G2 1
3 4 2
3 G3 2
4 G1 3
G2 G1 1
G3 G2 2
輸出樣例1:
G1
2.0 3.3
輸入樣例2:
2 1 2 10
1 G1 9
2 G1 20
輸出樣例2:
No Solution

#include <bits/stdc++.h>
#include <string>
using namespace std;
const int maxv = 10000;
const int INF = 1e9;

int N, M, K, Ds;//N+M總點數,K邊數
int m = K, G[maxv][maxv];
int d[maxv];
bool vis[maxv];

struct Node{
    int id;
    double d_min;
    double aver;
}ans[maxv];
bool cmp(Node a, Node b){
    if(a.d_min != b.d_min){
        return a.d_min > b.d_min;//最短距離最長
    }else{
        if(a.aver != b.aver) return a.aver < b.aver;
        else return a.id < b.id;
    }

}

void Dijkstra(int s){

    fill(d, d+maxv, INF);
    fill(vis, vis+maxv, 0);
    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(!vis[j] && d[j] < Min){
                u = j;
                Min = d[j];
            }
        }
        if(u == -1) return;
        vis[u] = true;
        //更新d[]

        for(int v = 1; v <= N+M; v++){

            if(vis[v] == false && G[u][v] != INF && d[v] > d[u]+G[u][v]){
                d[v] = d[u]+G[u][v];
            }
        }
    }

}

int change(string s){

    if(s[0] == 'G'){
        s.erase(0,1);
        int id = 0;
        stringstream ss(s);
        ss >> id;
        return id+N;
    }else{
        int id = 0;
        stringstream ss(s);
        ss >> id;
        return id;
    }


}

int main(){

    cin >> N >> M >> K >> Ds;
    string str1, str2;
    int w;
    fill(G[0], G[0]+ maxv*maxv , INF);
    for(int i = 0; i < K; i++){
        cin >> str1 >> str2 >> w;
        int id1 = change(str1);
        int id2 = change(str2);
        G[id1][id2] = w;
        G[id2][id1] = w;
    }
    int cnt = 0;
    for(int i = N+1; i <= N+M; i++){
        Dijkstra(i);
        bool flag = false;
        int sum = 0,t_min = INF;
        for(int j = 1; j <= N; j++){
            sum += d[j];
            t_min = min(t_min, d[j]);
            if(d[j] > Ds){
                flag = true;
                break;
            }
        }

        if(flag == false){
            ans[cnt].id = i;
            ans[cnt].d_min = t_min;
            ans[cnt++].aver = sum*1.0/N;
            //cout << i <<" "<< t_min << " "<<sum*1.0/N << endl;
        }
    }
    if(cnt == 0){
        cout << "No Solution" << endl;
    }else{
        sort(ans, ans+cnt,cmp);
        stringstream a;
        a << ans[0].id%N;
        cout << "G" << a.str() << endl;
        cout << fixed << setprecision(1) << ans[0].d_min+1e-8 <<" "<< ans[0].aver+1e-8 << endl;
    }



    return 0;
}

相關文章