A1072 Gas Station (30分)

一、技术总结

  1. 第一点是关于图的编号如何处理,因为气站混合在图中,同时编号带有因为字母,所以解决办法是把气站编号依次往居民编号后加即n+1开始。需要编写getID函数,将字符变为数字的公式为int ID = 0; ID = ID * 10 + (str[i]-'0');,具体参考代码处
  2. 第二点要注意题中要求,初始结点下标是从1开始还是从0开始,从而决定i <= n还是i < n,这点尤为重要,在编写Djikstra函数时。
  3. 还有就是题中的限制条件,这一步需要我们去仔细审读题目,查看样例。

二、参考代码

#include<bits/stdc++.h>
using namespace std;
const int MAXN = 1015;
const int INF = 0x3fffffff;
int G[MAXN][MAXN], d[MAXN];
bool vis[MAXN] = {false};
int n, m, k, ds;
//avgDis是符合站点要求到每个居民家的平均距离,
//ansMax是每个站点最短距离中的最大距离
//ansID最终存放加油站ID号 
double avgDis = INF, ansMax = -1; 
int ansID = -1;
void Djikstra(int s){
    memset(vis, false, sizeof(vis));
    fill(d, d+MAXN, INF);
    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] == false && d[j] < MIN){
                u = j;
                MIN = d[j];
            }
        }
        if(u == -1) return;
        vis[u] = true;
        for(int v = 1; v <= n+m; v++){
            if(vis[v] == false && G[u][v] != INF){
                if(d[u] + G[u][v] < d[v]){
                    d[v] = d[u] + G[u][v];
                }
            }
        }
    }
} 
//将str[]转换为数字,若str是数字,则返回本身,否则返回去掉G之后的数字加上n 
int getID(char str[]){
    int i = 0, len = strlen(str), ID = 0;
    while(i < len){
        if(str[i] != 'G'){
            ID = ID * 10 + (str[i] - '0');
        }
        i++;
    } 
    if(str[0] == 'G') return n + ID;
    else return ID;
}
int main(){
    scanf("%d%d%d%d", &n, &m, &k, &ds);
    int u, v, w;
    char c1[5], c2[5];
    fill(G[0], G[0]+MAXN*MAXN, INF);
    for(int i = 1; i <= k; i++){
        scanf("%s %s %d", c1, c2, &w);
        u = getID(c1);
        v = getID(c2);
        G[v][u] = G[u][v] = w;
    }
    //遍历所有加油站 
    for(int i = n+1; i <= n+m; i++){
        double minDis = INF, avg = 0;//minDis为最大的最近距离, avg为平均距离
        Djikstra(i);
        for(int j = 1; j <= n; j++){
            if(d[j] > ds){
                minDis = -1;
                break;
            }
            if(d[j] < minDis) minDis = d[j];
            avg += 1.0 * d[j] / n;//获取平均距离 
        } 
        if(minDis == -1) continue;
        if(minDis > ansMax){//更新最大距离 
            ansID = i;
            ansMax = minDis;
            avgDis = avg;
        }else if(minDis == ansMax && avg < avgDis){
            ansID = i;
            avgDis = avg;
        } 
    }
    if(ansID == -1) printf("No Solution\n");
    else{
        printf("G%d\n", ansID-n);
        printf("%.1f %.1f\n", ansMax, avgDis);
    } 
    return 0;    
}
上一篇:找出距离最小的点对


下一篇:Mindis 2019百度之星初赛第一轮