1072 Gas Station

该程序使用C++处理一个图论问题,寻找在给定居民点、候选公交站、道路和服务范围条件下,能覆盖最多居民点的最优公交站。通过深度优先搜索计算节点间最短距离,并基于特定条件(服务范围、平均距离)进行排序选择。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

int N,M,K,Ds;//N居民数,M候选站数,K路数,Ds服务范围
int dis[1011][1011];
vector<int>v[1011];
int mindis[1011];
int mindistohouse[1011],atservice[1011],totaldis[1011];

void dfs(int cur,int curdis){
    mindis[cur]=curdis;
    for(int each:v[cur]){
        int temp=curdis+dis[cur][each];
        if(temp<mindis[each])dfs(each,temp);
    }
}

bool comp(int x,int y){
    if(atservice[x]!=atservice[y])return atservice[x]>atservice[y];
    if(mindistohouse[x]!=mindistohouse[y])return mindistohouse[x]>mindistohouse[y];
    if(totaldis[x]!=totaldis[y])return totaldis[x]<totaldis[y];
    return x<y;
}

void read(int&p){
    char c;
    c=getchar();
    if(c=='G'){
        p=0;
        while(isdigit(c=getchar())){
            p=p*10+c-'0';
        }
        p+=N;
    }
    else{
        p=c-'0';
        while(isdigit(c=getchar())){
            p=p*10+c-'0';
        }
    }
}


int main()
{
    int i,j,k,l;
    cin>>N>>M>>K>>Ds;
    getchar();
    while(K--){
        read(j);
        read(k);
        read(l);
        v[k].emplace_back(j);
        v[j].emplace_back(k);
        dis[k][j]=dis[j][k]=l;
    }//输入
    
    for(i=N+1;i<=N+M;i++){
        for(j=1;j<=N+M;j++)mindis[j]=1000000000;
        dfs(i,0);
        //最短距离尽量远/都在服务范围内/平均距离尽量近/下标小
        mindistohouse[i]=1000000000;
        atservice[i]=1;
        totaldis[i]=0;
        for(j=1;j<=N;j++){
            if(mindis[j]<mindistohouse[i])mindistohouse[i]=mindis[j];
            if(mindis[j]>Ds){
                atservice[i]=0;
                break;
            }
            totaldis[i]+=mindis[j];
        }
    }
    
    int ans=N+1;
    for(i=N+2;i<=N+M;i++){
        if(comp(i,ans)==true)ans=i;
    }
    if(!atservice[ans]){
        cout<<"No Solution";
    }
    else{
        cout<<'G'<<ans-N<<endl;
        printf("%.1f %.1f",double(mindistohouse[ans]),double(totaldis[ans])/double(N));
    }
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

上官唐云

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值