GPLT L3-005. 垃圾箱分佈【最短路Dijkstra】

題目:垃圾箱分佈

題意:選一垃圾桶的位置到所有居民點距離最佳,“到所有居民點的最短距離最長的地方”意思就是將每個垃圾桶位置的到居民點最短的路中篩選最長的那個的垃圾桶作爲結果~

思路:將所有垃圾桶的位置利用Dijkstra依次搜出到各個居名點的最短路,然後加入到一個結構體數組中,注意當超出限制範圍無需加入,最後按要求排序即可。

注意輸入時需要用字符串處理,將G的加上n,即垃圾桶的編號爲n以後的數,注意編號不只是個位數~

代碼:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn = 1020;
const int inf = 999999999;
int g[maxn][maxn],dis[maxn],visit[maxn];
int n,m,k,ds;
struct bag{
    int id,mindis;
    double avg;
}ans[15];
bool cmp(bag a,bag b){
    if(a.mindis == b.mindis){
        if(a.avg == b.avg) return a.id < b.id;
        return a.avg < b.avg;
    }
    return a.mindis > b.mindis;//最短距離最長!
}
void init(){
    for(int i=1;i<=n+m;i++)
        for(int j=1;j<=n+m;j++)
            if(i == j) g[i][j] = 0;else g[i][j] = inf;
}
void Dijkstra(int start){
    for(int i=1;i<=n+m;i++){
        dis[i] = g[start][i];
    }
    visit[start] = 1;
    for(int i=1;i<=n+m;i++){
        int minn = inf,record;
        for(int j=1;j<=n+m;j++)
            if(dis[j] < minn && !visit[j]){minn = dis[j];record = j;}
        visit[record] = 1;
        for(int j=1;j<=n+m;j++){
            if(!visit[j] && dis[record] + g[record][j] < dis[j]){dis[j] = dis[record] + g[record][j];}
        }
    }
}
int trans(char a[],int start){

    int sum = 0;
    for(int i=start;a[i]!='\0';i++){sum*=10;sum += a[i] - '0';}
    return sum;
}
int main()
{
    char u[10],v[10];
    int dist;
    while(scanf("%d%d%d%d",&n,&m,&k,&ds)!=EOF){
        init();
        for(int i=0;i<k;i++){
            scanf("%s%s%d",u,v,&dist);
            int x,y;
            if(u[0] == 'G') x = trans(u,1)+n;else x = trans(u,0);
            if(v[0] == 'G') y = trans(v,1)+n;else y = trans(v,0);
            g[x][y] = g[y][x] = dist;
        }
        int cnt = 0;
        for(int i=n+1;i<=n+m;i++){
            memset(visit,0,sizeof(visit));
            Dijkstra(i);
            int sum = 0,msd = inf;
            int flag = 0;
            for(int j=1;j<=n;j++) {
                if(dis[j] > ds) {flag = 1;break;}//超出限制範圍
                sum += dis[j];
                msd = min(msd,dis[j]);//求垃圾桶到所有居民點最小距離
            }
            if(flag) continue;
            ans[cnt].id = i-n;
            ans[cnt].avg = (double)sum/n;
            ans[cnt++].mindis = msd;
        }
        sort(ans,ans+cnt,cmp);
        if(cnt > 0){
            printf("G%d\n%.1lf %.1lf\n",ans[0].id,(double)ans[0].mindis,ans[0].avg);
        }else printf("No Solution\n");
    }
    return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章