2021-04-06 PAT A1072

测试点3坑了我3个小时。。。。。
因为他的最短距离就是最远的服务范围

#include<cstdio>
#include<cstring>
#include<vector>
#include<utility>
#include<queue>
#include<algorithm>
using namespace std;
const int maxn = 1020, INF = 0x3fffffff;
int n, m, k, DS, dis[maxn];//index代表的是候选位置插入的编号
bool vis[maxn];
vector<pair<int, int> > graph[maxn];//第一个项是ID,第二个是距离
int getID(char* name) {
    if (name[0] == 'G') {
        int len = strlen(name);
        for (int i = 0; i < len; i++)name[i] = name[i + 1];
        return n + atoi(name);
    }
    return atoi(name);
}
int main() {
    scanf("%d %d %d %d", &n, &m, &k, &DS); getchar();
    for (int i = 0; i < k; i++) {
        char name_A[6], name_B[6]; int w;
        scanf("%s %s %d", name_A, name_B, &w);getchar();
        int A_ID = getID(name_A), B_ID = getID(name_B);
        graph[A_ID].push_back(pair<int, int>(B_ID, w));
        graph[B_ID].push_back(pair<int, int>(A_ID, w));
    }
    float averagedis = 999999999.0;
    int length = -1,  code = -1;//用来记录最大的最短距离
    for (int i = n + 1; i <= n + m; i++) {//使用dij
        priority_queue<pair<int, int>, vector<pair<int, int> >, greater<pair<int, int> > > q;
        memset(vis, 0, sizeof vis);
        fill(dis, dis + maxn, INF);
        q.push(pair<int, int>(0, i)); dis[i] = 0;
        for (int j = 0; j < n + m; j++) {//因为其中有n + m个点,要让每个点都松弛到,所以要松弛n + m 次
            if (q.empty())break;
            pair<int, int> temp = q.top(); q.pop(); vis[temp.second] = true;
            int u = temp.second;
            for (int k = 0; k < graph[u].size(); k++) {
                int  v = graph[u][k].first, w = graph[u][k].second;
                if (!vis[v] && dis[u] + w < dis[v]) {
                    dis[v] = dis[u] + w;
                    //vis[v] = true;只有弹栈的时候才停止,没有弹栈之前,他都有被松弛的可能
                    q.push(pair<int, int>(dis[v],v));
                }
            }
        }
        int temp_length = INF;
        double temp_average = 0.0;
        for (int j = 1; j <= n; j++) { 
            if ( dis[j] > DS) { temp_length = dis[j]; break;} 
            if (dis[j] < temp_length)temp_length = dis[j];//找到距离加油站最近的距离
            temp_average += (double) dis[j]; 
        }
        if (temp_length <= DS) {
            temp_average /= (double) n;//求出平均距离
            if (temp_length > length) {
                code = i;//记下最合适的加油站
                length = temp_length;
                averagedis = temp_average;
            }
            else if (temp_length == length && temp_average < averagedis) {
                code = i;//记下最合适的加油站
                averagedis = temp_average;
            }
        }
    }
    if (code == -1) printf("No Solution\n");
    else printf("G%d\n%.01f %.01f\n", code - n, (double)length, averagedis);
    return 0;
}
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • [TOC] 一、题目描述 你现在手里有一份大小为 N x N 的『地图』(网格) grid,上面的每个『区域』(单...
    RuriApoka阅读 399评论 0 0
  • 题目 要建一个加油站。地图里有N个房子,M个加油站备选地址,K条道路连接他们,而且有一参数Ds是加油站的服务范围长...
    胖胖的熊管家阅读 157评论 0 1
  • 最近做了一个算法题【盒马配货】: (题目大意)盒马店的配送范围由一些点组成的多边形确定,给定一个点判断其是否在配送...
    亮爷也风流阅读 6,348评论 0 4
  • 1 判断类问题 判断类问题主要分判断二叉树是否是二叉搜索树、二叉完全树,以及两棵二叉树是否同构这三个问题。 1.1...
    桑榆非晚95阅读 1,131评论 0 0
  • 今天感恩节哎,感谢一直在我身边的亲朋好友。感恩相遇!感恩不离不弃。 中午开了第一次的党会,身份的转变要...
    迷月闪星情阅读 10,624评论 0 11