博客
关于我
程序设计基础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/

    你可能感兴趣的文章
    mysqli
    查看>>
    MySQLIntegrityConstraintViolationException异常处理
    查看>>
    mysqlreport分析工具详解
    查看>>
    MySQLSyntaxErrorException: Unknown error 1146和SQLSyntaxErrorException: Unknown error 1146
    查看>>
    Mysql_Postgresql中_geometry数据操作_st_astext_GeomFromEWKT函数_在java中转换geometry的16进制数据---PostgreSQL工作笔记007
    查看>>
    mysql_real_connect 参数注意
    查看>>
    mysql_secure_installation初始化数据库报Access denied
    查看>>
    MySQL_西安11月销售昨日未上架的产品_20161212
    查看>>
    Mysql——深入浅出InnoDB底层原理
    查看>>
    MySQL“被动”性能优化汇总
    查看>>
    MySQL、HBase 和 Elasticsearch:特点与区别详解
    查看>>
    MySQL、Redis高频面试题汇总
    查看>>
    MYSQL、SQL Server、Oracle数据库排序空值null问题及其解决办法
    查看>>
    mysql一个字段为空时使用另一个字段排序
    查看>>
    MySQL一个表A中多个字段关联了表B的ID,如何关联查询?
    查看>>
    MYSQL一直显示正在启动
    查看>>
    MySQL一站到底!华为首发MySQL进阶宝典,基础+优化+源码+架构+实战五飞
    查看>>
    MySQL万字总结!超详细!
    查看>>
    Mysql下载以及安装(新手入门,超详细)
    查看>>
    MySQL不会性能调优?看看这份清华架构师编写的MySQL性能优化手册吧
    查看>>