团体程序设计天梯赛(L3-005 垃圾箱分布 (30 分))

题目:

思路分析:

枚举垃圾桶

多次dij来求到垃圾桶的最短距离

代码实现:

/*
*@Author:   GuoJinlong
*@Language: C++
*/
//#include <bits/stdc++.h>
/*
 *                                                     __----~~~~~~~~~~~------___
 *                                    .  .   ~~//====......          __--~ ~~
 *                    -.            \_|//     |||\\  ~~~~~~::::... /~
 *                 ___-==_       _-~o~  \/    |||  \\            _/~~-
 *         __---~~~.==~||\=_    -_--~/_-~|-   |\\   \\        _/~
 *     _-~~     .=~    |  \\-_    '-~7  /-   /  ||    \      /
 *   .~       .~       |   \\ -_    /  /-   /   ||      \   /
 *  /  ____  /         |     \\ ~-_/  /|- _/   .||       \ /
 *  |~~    ~~|--~~~~--_ \     ~==-/   | \~--===~~        .\
 *           '         ~-|      /|    |-~\~~       __--~~
 *                       |-~~-_/ |    |   ~\_   _-~            /\
 *                            /  \     \__   \/~                \__
 *                        _--~ _/ | .-~~____--~-/                  ~~==.
 *                       ((->/~   '.|||' -_|    ~~-/ ,              . _||
 *                                  -_     ~\      ~~---l__i__i__i--~~_/
 *                                  _-~-__   ~)  \--______________--~~
 *                                //.-~~~-~_--~- |-------~~~~~~~~
 *                                       //.-~~~--\
 *                       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 *
 *                               神兽保佑            永无BUG
 */


 
const int maxn = 1020;

int g[maxn][maxn];
int d[maxn];
bool visit[maxn];
 
int n,m,k,ds;
 
void disjk(int s){
    memset(d,INF,sizeof(d));
    memset(visit,0,sizeof(visit));
    d[s] = 0;
 
    while(1){
        int u = -1;
        ///从未选取的点中找一个离起点最近的点,这里要包括垃圾桶待选点
        for(int i = 1; i <= n+m; ++i){
            if(visit[i]) continue;
            if(u == -1 || d[i] < d[u])
                u = i;
        }
        if(u==-1) return;
 
        visit[u] = true;
 
        ///更新和这个点相接的点
        for(int i = 1;i <= n+m; ++i){
            if(d[u]+g[u][i] < d[i]){
                d[i] = d[u]+g[u][i];
            }
        }
    }
}
 
int mchange(char a[]){
    int len = strlen(a);
    int ans = 0;
    if(a[0] == 'G'){
        for(int i = 1; i < len; ++i){
            ans = ans*10+a[i]-'0';
        }
        ans += n;
    }
 
    else {
        for(int i = 0; i < len; ++i){
            ans = ans*10+a[i]-'0';
        }
    }
    return ans;
}
 
 
int main(){
 
    memset(g,INF,sizeof(g));
    scanf("%d%d%d%d",&n,&m,&k,&ds);
    char a[5];
    char b[5];
    int u,v,w;
    for(int i = 0; i < k; ++i){
        scanf("%s%s%d",a,b,&w);
        u = mchange(a);
        v = mchange(b);
        g[u][v] = w;
        g[v][u] = w;
    }
 
    int ansnum = 0;
    double aveminn = INF;
    double mmin = 0;
    int ans ;
    for(int i = n+1;i<=n+m; ++i){
        disjk(i);
        int  f = 1;
        double sum = 0;
        double tmin = INF;
 
        ///判断有没有超过最大距离的同时把最小的距离求出来
        ///这里只需要看居民点和当前垃圾桶点就行了
        for(int j = 1; j <= n; ++j){
            if(d[j] > ds) {f = 0; break;}
            if(d[j] < tmin) tmin = d[j];
            sum += d[j];
        }
        if(!f) continue;
        ansnum ++;
        sum /= n;
        if(tmin > mmin){///最短的当中最长的一个
            aveminn = sum;
            ans = i-n;
            mmin = tmin;
        }
        else if(tmin == mmin){
            if(aveminn > sum){
                aveminn = sum;
                ans = i-n;
                mmin = tmin;
            }
        }
    }
    if(ansnum==0) printf("No Solution");
 
    else {
        printf("G");
        printf("%d\n%.1f %.1f",ans,mmin,aveminn);
    }
 
    return 0;
}

猜你喜欢

转载自blog.csdn.net/m0_57006708/article/details/121227697