当前位置:首页 > 牛客题解 > 牛客17722题解:拓扑排序识别金融安全客户

牛客17722题解:拓扑排序识别金融安全客户

2天前牛客题解53

截图未命名.jpg 牛客17722题解:拓扑排序识别金融安全客户 拓扑排序 邻接表 图论算法 牛客题解 C++ 队列 第1张

一、问题背景

牛客17722题模拟了一个金融借贷网络,要求识别出"安全客户"——即不会陷入循环借贷的客户。这类问题在金融风控、依赖分析等领域很常见。

二、算法核心思想

  1. 建模‌:将客户关系建模为有向图

  2. 拓扑排序‌:反向应用拓扑排序识别安全节点

  3. 出度统计‌:通过出度数组动态更新节点状态

三、完整代码实现(带注释)

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

vector<vector<int>> graph;  // 邻接表存储图
vector<int> out_degree;     // 出度数组
vector<bool> is_safe;       // 标记是否为安全客户

void mark_safe_customers(int n) {
    queue<int> q;
    // 初始化:出度为0的节点是安全的
    for (int i = 1; i <= n; ++i) {
        if (out_degree[i] == 0) {
            q.push(i);
            is_safe[i] = true;
        }
    }
    
    // 拓扑排序过程
    while (!q.empty()) {
        int u = q.front();
        q.pop();
        
        // 遍历所有指向u的节点
        for (int v = 1; v <= n; ++v) {
            if (find(graph[v].begin(), graph[v].end(), u) != graph[v].end()) {
                out_degree[v]--;
                if (out_degree[v] == 0 && !is_safe[v]) {
                    is_safe[v] = true;
                    q.push(v);
                }
            }
        }
    }
}

int main() {
    int n, m;
    cin >> n >> m;
    
    graph.resize(n + 1);
    out_degree.resize(n + 1, 0);
    is_safe.resize(n + 1, false);
    
    // 读取边关系并构建图
    for (int i = 0; i < m; ++i) {
        int u, v;
        char comma;
        cin >> u >> comma >> v;
        graph[u].push_back(v);
        out_degree[u]++;
    }
    
    mark_safe_customers(n);
    
    // 收集所有安全客户
    vector<int> safe_list;
    for (int i = 1; i <= n; ++i) {
        if (is_safe[i]) {
            safe_list.push_back(i);
        }
    }
    
    // 输出结果
    if (safe_list.empty()) {
        cout << "None";
    } else {
        for (int i = 0; i < safe_list.size(); ++i) {
            if (i > 0) cout << " ";
            cout << safe_list[i];
        }
    }
    
    return 0;
}


四、关键知识点

  1. 邻接表‌:高效存储稀疏图的数据结构

  2. 拓扑排序‌:解决依赖关系的经典算法

  3. 出度统计‌:判断节点安全性的核心指标

  4. 队列应用‌:广度优先的节点处理顺序


原创内容 转载请注明出处

分享给朋友:

发表评论

访客

看不清,换一张

◎欢迎参与讨论,请在这里发表您的看法和观点。