博客
关于我
程序设计基础81 图之无向图防止回头和访问通向已访问结点的路径
阅读量:387 次
发布时间:2019-03-05

本文共 2512 字,大约阅读时间需要 8 分钟。

为了解决这个问题,我们需要识别电话联系网络中的“团伙”(Gang),其中每个团伙中的成员通过电话联系,总联系时间超过阈值K,且成员数量超过2。团伙的头头是联系时间最长的成员。

方法思路

  • 图的表示:将电话联系视为无向图,每条边表示通话,边权重为通话时间。
  • 遍历连通块:使用深度优先搜索(DFS)遍历图中的每个连通块,计算每个连通块的总联系时间和成员数量。
  • 判断团伙:检查每个连通块的总联系时间是否超过K,且成员数量是否超过2。如果满足条件,记录该连通块的头头和成员数量。
  • 排序和输出:按头头的名字排序,输出结果。
  • 解决代码

    #include 
    #include
    #include
    #include
    #include
    #include
    using namespace std;struct Node { int id; int total;};void convert_name_to_id(map
    & name_to_id, string name) { if (name_to_id.find(name) == name_to_id.end()) { name_to_id[name] = name_to_id.size() + 1000; }}void dfs(int u, int &currentTotalTime, int &maxPerson, int &count, const vector
    >& adj, const map
    & id_to_name, vector
    & visited) { if (visited[u]) { return; } visited[u] = true; count++; if (PersonTimes[u] > maxPerson) { maxPerson = u; } for (int v = 0; v < max_n; v++) { if (!visited[v] && adj[u][v] > 0) { currentTotalTime += adj[u][v]; dfs(v, currentTotalTime, maxPerson, count, adj, id_to_name, visited); adj[u][v] = 0; // 防止重复处理边 } }}int main() { map
    name_to_id; map
    id_to_name; const int max_n = 2020; int N, K; vector
    > adj(max_n, vector
    (max_n, 0)); int PersonTimes[max_n] = {0}; vector
    visited(max_n, false); // 读取输入 scanf("%d %d", &N, &K); // 读取通话记录 for (int i = 0; i < N; i++) { string str1, str2, str3; scanf("%s %s %d", &str1, &str2, &str3); // 转换名字为id convert_name_to_id(name_to_id, str1); convert_name_to_id(name_to_id, str2); int u = name_to_id[str1]; int v = name_to_id[str2]; int time = str3 - '0'; // 更新邻接矩阵和邻接表 adj[u][v] += time; adj[v][u] += time; // 更新总联系时间 PersonTimes[u] += time; PersonTimes[v] += time; } // 遍历每个节点 vector
    gangs; for (int u = 0; u < max_n; u++) { if (visited[u]) { continue; } int currentTotalTime = 0; int maxPerson = u; int count = 1; vector
    current_visited(max_n, false); current_visited[u] = true; // 进行DFS dfs(u, currentTotalTime, maxPerson, count, adj, id_to_name, current_visited); // 检查条件 if (currentTotalTime > K && count > 2) { Node gang; gang.id = maxPerson; gang.total = count; gangs.push_back(gang); } } // 按名字排序 sort(gangs.begin(), gangs.end(), [](const Node& a, const Node& b) { return id_to_name[a.id] < id_to_name[b.id]; }); // 输出 cout << gangs.size() << endl; for (const auto& gang : gangs) { cout << id_to_name[gang.id] << " " << gang.total << endl; } return 0;}

    代码解释

  • 输入处理:读取输入数据,解析每个通话,更新邻接矩阵和总联系时间数组。
  • 名字映射:将每个名字转换为唯一的整数索引,便于图的表示。
  • DFS遍历:使用DFS遍历每个连通块,计算总联系时间和成员数量。
  • 团伙判断:检查连通块是否满足团伙条件,记录头头和成员数量。
  • 排序和输出:按头头名字排序,输出结果。
  • 通过这种方法,我们可以有效地识别和处理电话联系网络中的团伙,确保输出符合要求。

    转载地址:http://imlwz.baihongyu.com/

    你可能感兴趣的文章
    MySql中mvcc学习记录
    查看>>
    mysql中null和空字符串的区别与问题!
    查看>>
    MySQL中ON DUPLICATE KEY UPDATE的介绍与使用、批量更新、存在即更新不存在则插入
    查看>>
    MYSQL中TINYINT的取值范围
    查看>>
    MySQL中UPDATE语句的神奇技巧,让你操作数据库如虎添翼!
    查看>>
    Mysql中varchar类型数字排序不对踩坑记录
    查看>>
    MySQL中一条SQL语句到底是如何执行的呢?
    查看>>
    MySQL中你必须知道的10件事,1.5万字!
    查看>>
    MySQL中使用IN()查询到底走不走索引?
    查看>>
    Mysql中使用存储过程插入decimal和时间数据递增的模拟数据
    查看>>
    MySql中关于geometry类型的数据_空的时候如何插入处理_需用null_空字符串插入会报错_Cannot get geometry object from dat---MySql工作笔记003
    查看>>
    mysql中出现Incorrect DECIMAL value: '0' for column '' at row -1错误解决方案
    查看>>
    mysql中出现Unit mysql.service could not be found 的解决方法
    查看>>
    mysql中出现update-alternatives: 错误: 候选项路径 /etc/mysql/mysql.cnf 不存在 dpkg: 处理软件包 mysql-server-8.0的解决方法(全)
    查看>>
    Mysql中各类锁的机制图文详细解析(全)
    查看>>
    MySQL中地理位置数据扩展geometry的使用心得
    查看>>
    Mysql中存储引擎简介、修改、查询、选择
    查看>>
    Mysql中存储过程、存储函数、自定义函数、变量、流程控制语句、光标/游标、定义条件和处理程序的使用示例
    查看>>
    mysql中实现rownum,对结果进行排序
    查看>>
    mysql中对于数据库的基本操作
    查看>>