• PAT甲级1034Head of a Gang


    题目链接

    https://pintia.cn/problem-sets/994805342720868352/problems/994805456881434624

    题解

    题目要求

    • 背景

      A和B打电话,则A和B有关系,A和B关系的权重为他们间通话的总时长。

      一个帮派由2个人以上组成,他们关系的总权重超过K。

      帮派中和别人关系的总权重最大的人就是头目。现给出多个通话,请找出头目。

    • 输入

      • N:正整数,不超过1000,通话的数量
      • K:正整数,不超过1000,权重阈值
      • N个通话
    • 输出

      • 帮派的数量
      • 每个帮派的头目和成员数量(按头目名称的字典序输出)

    解题思路

    • 通过map保存名字和索引的关系。

    • 一个帮派就是一个连通分量

    • 通过DFS求有多少个连通分量,通过成员数量和总权重进行筛选,最终输出其结点数和头目

    • 题目有个地方很奇怪?要把题目理解对了

      In each gang, the one with maximum total weight is the head. 这句话指出在每个帮派中,总权重最大的人就是头目。

      我起初理解为应在这个帮派之内求每个人的权重(如果A属于某帮派而B不属于这个帮派,那计算A的总权重时,则不应该将A和B的权重包含在内)。但题目的意思是在所有人范围内计算总权重,即使帮派里不包含B,计算A的总权重时也要将A和B的权重计入。

    代码

    // Problem: PAT Advanced 1034
    // URL: https://pintia.cn/problem-sets/994805342720868352/problems/994805456881434624
    // Tags: 图 连通分量 map DFS
    
    #include <iostream>
    #include <string>
    #include <map>
    using namespace std;
    
    map<string, int> sti;
    map<int, string> its;
    map<string, int> ans;
    const int MAXN = 2001; // 最多1000个通话,最多就有2000个人
    int id = 1;
    int e[MAXN][MAXN];
    int weight[MAXN];
    bool visited[MAXN];
    
    void dfs(int u, int& head, int& totalWeight, int& memberCount){
        visited[u] = true;
        memberCount += 1;
        if (weight[u] > weight[head]){
            head = u;
        }
        for (int v = 1; v < id; v++){
            if (e[u][v] > 0){
                totalWeight += e[u][v]; // 在所有人范围内计算总权重
                e[u][v] = e[v][u] = 0;
                if (!visited[v])
                    dfs(v, head, totalWeight, memberCount);
            }
        }
    }
    
    int main()
    {
        int n, k;
        scanf("%d %d", &n, &k);
    
        string s1, s2;
        int t;
        for (int i = 0; i < n; i++){
            cin >> s1 >> s2;
            scanf("%d", &t);
            if (sti[s1] == 0){
                sti[s1] = id;
                its[id] = s1;
                id++;
            }
            if (sti[s2] == 0){
                sti[s2] = id;
                its[id] = s2;
                id++;
            }
            e[sti[s1]][sti[s2]] += t;
            e[sti[s2]][sti[s1]] += t;
            weight[sti[s1]] += t;
            weight[sti[s2]] += t;
        }
    
        for (int i = 1; i < id; i++){
            if (!visited[i]){
                int head = i, totalWeight = 0, memberCount = 0;
                dfs(i, head, totalWeight, memberCount);
                if (memberCount > 2 && totalWeight > k)
                    ans[its[head]] = memberCount;
            }
    
        }
    
        printf("%d
    ", ans.size());
        for (auto it = ans.begin(); it != ans.end(); it++)
            printf("%s %d
    ", it->first.c_str(), it->second);
    
        return 0;
    }
    

    作者:@臭咸鱼

    转载请注明出处:https://www.cnblogs.com/chouxianyu/

    欢迎讨论和交流!


  • 相关阅读:
    three.js 制作一个三维的推箱子游戏
    three.js 郭先生制作太阳系
    three.js 制作魔方
    three.js 欧拉角和四元数
    mysql
    重装系统后需要安装的软件
    python3.7 安装PyQt5
    Java读取文件
    linux 环境jdk安装
    linux 修改用户字符集
  • 原文地址:https://www.cnblogs.com/chouxianyu/p/13735860.html
Copyright © 2020-2023  润新知