1989年IOI最后一题题解C++(六种语言版)

中文版:

题目描述

1989年IOI最后一题是关于通信网络优化的经典问题。具体描述如下:

给定一个包含n个节点的通信网络(节点编号1~n),其中部分节点间存在双向通信线路,每条线路具有固定带宽。现需从节点1向节点n传输数据,要求找出使路径最小带宽最大的传输路径,并输出该最大最小带宽值。

输入格式

  • 首行两个整数n和m,表示节点数和线路数
  • 后续m行,每行三个整数u、v、b,表示节点u和v之间存在带宽为b的通信线路

输出格式

  • 一个整数,表示1到n路径中的最大最小带宽

解题思路

该问题可转化为最大瓶颈路径问题,核心解法包括最大生成树法和二分查找+BFS/DFS法。

方法一:最大生成树

最大生成树中任意两点路径的最小边权即为所有可能路径中的最大最小带宽。

算法步骤

  1. 将边按带宽降序排序
  2. 使用Kruskal算法构建最大生成树
  3. 在生成树中用DFS/BFS找出1到n的路径,记录最小边权

方法二:二分查找+BFS
算法步骤

  1. 确定二分范围:左边界0,右边界为最大边带宽
  2. 每次取mid值,检查是否存在1到n路径满足所有边带宽≥mid
  3. 存在则尝试更大的mid,否则尝试更小的
  4. 最终得到的最大可行mid即为解

C++实现(二分+BFS)

cpp 复制代码
#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;

struct Edge {
    int u, v, b;
    Edge(int u, int v, int b) : u(u), v(v), b(b) {}
};

bool hasPath(const vector<vector<Edge>>& graph, int n, int min_b) {
    vector<bool> visited(n+1, false);
    queue<int> q{{1}};
    visited[1] = true;
    
    while (!q.empty()) {
        int u = q.front();
        q.pop();
        if (u == n) return true;
        
        for (const Edge& e : graph[u]) {
            if (!visited[e.v] && e.b >= min_b) {
                visited[e.v] = true;
                q.push(e.v);
            }
        }
    }
    return false;
}

int main() {
    int n, m;
    cin >> n >> m;
    
    vector<vector<Edge>> graph(n+1);
    vector<int> bandwidths;
    
    for (int i = 0; i < m; ++i) {
        int u, v, b;
        cin >> u >> v >> b;
        graph[u].emplace_back(u, v, b);
        graph[v].emplace_back(v, u, b);
        bandwidths.push_back(b);
    }
    
    int low = 0, high = *max_element(bandwidths.begin(), bandwidths.end());
    int res = 0;
    
    while (low <= high) {
        int mid = low + (high - low)/2;
        if (hasPath(graph, n, mid)) {
            res = mid;
            low = mid + 1;
        } else {
            high = mid - 1;
        }
    }
    
    cout << res << endl;
    return 0;
}

代码说明

  1. Edge结构体存储边信息
  2. hasPath函数用BFS检查是否存在满足条件的路径
  3. 主函数:
    • 构建邻接表
    • 二分查找确定最大最小带宽
    • 输出结果

复杂度分析

  • 时间:O((n+m)logB)
  • 空间:O(n+m)

测试用例

输入:

cpp 复制代码
4 5
1 2 3
1 3 2
2 3 4
2 4 2
3 4 3

输出:

cpp 复制代码
3

说明:路径1→2→3→4的最小带宽3为最优解。

英文版:

Problem Description

The final problem from the 1989 IOI is a classic communication network optimization problem. Here's the detailed description:

Given a communication network with n nodes (numbered 1 to n), some pairs of nodes are connected by bidirectional communication lines, each with a fixed bandwidth. The task is to transmit data from node 1 to node n along a path such that the minimum bandwidth along the path is maximized. Output this maximum minimum bandwidth.

Input Format

  • The first line contains two integers n and m, denoting the number of nodes and communication lines.
  • The next m lines each contain three integers u, v, and b, indicating a bidirectional line between nodes u and v with bandwidth b.

Output Format

  • A single integer representing the maximum minimum bandwidth among all paths from node 1 to node n.

Approach

This problem can be transformed into finding the maximum bottleneck path, where the minimum edge weight along the path is maximized. Two efficient approaches are presented:

Method 1: Maximum Spanning Tree

In a maximum spanning tree, the path between any two nodes has the highest possible minimum edge weight compared to all other possible paths.

Algorithm Steps

  1. Sort all edges in descending order of their bandwidths.
  2. Construct the maximum spanning tree using Kruskal's algorithm.
  3. Use DFS/BFS on the maximum spanning tree to find the path from node 1 to node n, tracking the minimum edge weight along this path.

Method 2: Binary Search + BFS

Algorithm Steps

  1. Define the binary search range: left = 0 (minimum possible bandwidth) and right = max(bandwidths) (maximum edge bandwidth).
  2. For each midpoint mid in the binary search:
    • Check if there exists a path from node 1 to node n where all edges have bandwidth ≥ mid.
    • If such a path exists, update the result and search in the higher half (left = mid + 1).
    • Otherwise, search in the lower half (right = mid - 1).
  3. The final result is the maximum feasible mid.

C++ Implementation (Binary Search + BFS)

cpp 复制代码
#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;

struct Edge {
    int u, v, b;
    Edge(int u, int v, int b) : u(u), v(v), b(b) {}
};

bool hasPath(const vector<vector<Edge>>& graph, int n, int min_b) {
    vector<bool> visited(n+1, false);
    queue<int> q{{1}};
    visited[1] = true;
    
    while (!q.empty()) {
        int u = q.front();
        q.pop();
        if (u == n) return true;
        
        for (const Edge& e : graph[u]) {
            if (!visited[e.v] && e.b >= min_b) {
                visited[e.v] = true;
                q.push(e.v);
            }
        }
    }
    return false;
}

int main() {
    int n, m;
    cin >> n >> m;
    
    vector<vector<Edge>> graph(n+1);
    vector<int> bandwidths;
    
    for (int i = 0; i < m; ++i) {
        int u, v, b;
        cin >> u >> v >> b;
        graph[u].emplace_back(u, v, b);
        graph[v].emplace_back(v, u, b);
        bandwidths.push_back(b);
    }
    
    int low = 0, high = *max_element(bandwidths.begin(), bandwidths.end());
    int res = 0;
    
    while (low <= high) {
        int mid = low + (high - low)/2;
        if (hasPath(graph, n, mid)) {
            res = mid;
            low = mid + 1;
        } else {
            high = mid - 1;
        }
    }
    
    cout << res << endl;
    return 0;
}

Code Explanation

  • Edge Struct : Stores edge information (nodes u, v, and bandwidth b).
  • hasPath Function : Uses BFS to check if a valid path exists with all edges ≥ min_b.
  • Main Function :
    1. Builds an adjacency list from input.
    2. Uses binary search to determine the maximum feasible minimum bandwidth.
    3. Outputs the result.

Complexity Analysis

  • Time: O((n + m) log B), where B is the maximum edge bandwidth.
  • Space: O(n + m) for storing the graph and BFS queue.

Test Case
Input:

cpp 复制代码
4 5
1 2 3
1 3 2
2 3 4
2 4 2
3 4 3

Output:

cpp 复制代码
3

Explanation : The path 1 → 2 → 3 → 4 has a minimum bandwidth of 3, which is optimal.

法文版:

Description du problème

Le dernier problème de l'IOI 1989 est un problème classique d'optimisation de réseau de communication. Voici la description détaillée :

Étant donné un réseau de communication comportant n nœuds (numérotés de 1 à n), certains paires de nœuds sont reliées par des liaisons de communication bidirectionnelles, chacune ayant une bande passante fixe. La tâche consiste à transmettre des données du nœud 1 au nœud n le long d'un chemin tel que la bande passante minimale le long du chemin soit maximisée. Sortez cette bande passante minimale maximale.

Format d'entrée

  • La première ligne contient deux entiers n et m, représentant le nombre de nœuds et le nombre de liaisons de communication.
  • Les m lignes suivantes contiennent chacune trois entiers u, v et b, indiquant une liaison bidirectionnelle entre les nœuds u et v avec une bande passante b.

Format de sortie

  • Un seul entier représentant la bande passante minimale maximale parmi tous les chemins du nœud 1 au nœud n.

Approche

Ce problème peut être transformé en recherche du chemin à goulot d'étranglement maximal, où le poids minimal des arêtes le long du chemin est maximisé. Deux approches efficaces sont présentées :

Méthode 1 : Arbre couvrant maximal

Dans un arbre couvrant maximal, le chemin entre deux nœuds quelconques a le plus grand poids minimal d'arête possible par rapport à tous les autres chemins possibles.

Étapes de l'algorithme

  1. Trier toutes les arêtes par ordre décroissant de leurs bandes passantes.
  2. Construire l'arbre couvrant maximal en utilisant l'algorithme de Kruskal.
  3. Utiliser DFS/BFS sur l'arbre couvrant maximal pour trouver le chemin du nœud 1 au nœud n, en suivant le poids minimal des arêtes le long de ce chemin.

Méthode 2 : Recherche binaire + BFS

Étapes de l'algorithme

  1. Définir la plage de recherche binaire : gauche = 0 (bande passante minimale possible) et droite = max(bandes passantes) (bande passante maximale des arêtes).
  2. Pour chaque point milieu milieu de la recherche binaire :
    • Vérifier s'il existe un chemin du nœud 1 au nœud n où toutes les arêtes ont une bande passante ≥ milieu.
    • Si un tel chemin existe, mettre à jour le résultat et rechercher dans la moitié supérieure (gauche = milieu + 1).
    • Sinon, rechercher dans la moitié inférieure (droite = milieu - 1).
  3. Le résultat final est le milieu maximal réalisable.

Implémentation C++ (Recherche binaire + BFS)

cpp 复制代码
#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;

struct Edge {
    int u, v, b;
    Edge(int u, int v, int b) : u(u), v(v), b(b) {}
};

bool hasPath(const vector<vector<Edge>>& graph, int n, int min_b) {
    vector<bool> visited(n+1, false);
    queue<int> q{{1}};
    visited[1] = true;
    
    while (!q.empty()) {
        int u = q.front();
        q.pop();
        if (u == n) return true;
        
        for (const Edge& e : graph[u]) {
            if (!visited[e.v] && e.b >= min_b) {
                visited[e.v] = true;
                q.push(e.v);
            }
        }
    }
    return false;
}

int main() {
    int n, m;
    cin >> n >> m;
    
    vector<vector<Edge>> graph(n+1);
    vector<int> bandwidths;
    
    for (int i = 0; i < m; ++i) {
        int u, v, b;
        cin >> u >> v >> b;
        graph[u].emplace_back(u, v, b);
        graph[v].emplace_back(v, u, b);
        bandwidths.push_back(b);
    }
    
    int low = 0, high = *max_element(bandwidths.begin(), bandwidths.end());
    int res = 0;
    
    while (low <= high) {
        int mid = low + (high - low)/2;
        if (hasPath(graph, n, mid)) {
            res = mid;
            low = mid + 1;
        } else {
            high = mid - 1;
        }
    }
    
    cout << res << endl;
    return 0;
}

Explication du code

  • Structure Edge : Stocke les informations sur les arêtes (nœuds u, v et bande passante b).
  • Fonction hasPath : Utilise BFS pour vérifier si un chemin valide existe avec toutes les arêtes ≥ min_b.
  • Fonction principale :
    1. Construit une liste d'adjacence à partir de l'entrée.
    2. Utilise une recherche binaire pour déterminer la bande passante minimale maximale réalisable.
    3. Affiche le résultat.

Analyse de la complexité

  • Temps : O((n + m) log B), où B est la bande passante maximale des arêtes.
  • Espace : O(n + m) pour stocker le graphe et la file d'attente BFS.

Exemple de test
Entrée :

cpp 复制代码
4 5
1 2 3
1 3 2
2 3 4
2 4 2
3 4 3

Sortie :

cpp 复制代码
3

Explication : Le chemin 1 → 2 → 3 → 4 a une bande passante minimale de 3, ce qui est optimal.

俄文版:

Описание задачи

Последняя задача IOI 1989 года представляет собой классическую задачу оптимизации коммуникационной сети. Подробное описание:

Имеется сеть из n узлов (нумеруемых от 1 до n), некоторые из которых соединены двунаправленными связями с фиксированной пропускной способностью. Требуется передать данные от узла 1 к узлу n по пути, при котором минимальная пропускная способность на этом пути будет максимально возможной. Вывести значение этой максимальной минимальной пропускной способности.

Формат входных данных

  • Первая строка содержит два целых числа n и m --- количество узлов и связей.
  • Следующие m строк содержат по три целых числа u, v и b, обозначающих двунаправленную связь между узлами u и v с пропускной способностью b.

Формат выходных данных

  • Одно целое число --- максимальная минимальная пропускная способность среди всех путей от узла 1 к узлу n.

Решение

Эта задача сводится к поиску максимального пути с минимальным ребрам, где минимальный вес ребра на пути является максимальным из всех возможных путей. Предлагаются два эффективных подхода:

Метод 1: Максимальное остовное дерево

В максимальном остовном дереве путь между любыми двумя узлами имеет наивысшую возможную минимальную пропускную способность по сравнению с другими путями.

Алгоритм

  1. Отсортировать все ребра по убыванию пропускной способности.
  2. Построить максимальное остовное дерево с использованием алгоритма Крускала.
  3. Найти путь от узла 1 к узлу n в построенном дереве с использованием DFS/BFS, отслеживая минимальный вес ребра на этом пути.

Метод 2: Двоичный поиск + BFS

Алгоритм

  1. Определить границы для двоичного поиска: left = 0 (минимальная возможная пропускная способность) и right = max(bandwidths) (максимальная пропускная способность среди всех ребер).
  2. Для каждой середины mid в диапазоне двоичного поиска:
    • Проверить, существует ли путь от узла 1 к узлу n, где все ребра имеют пропускную способность ≥ mid.
    • Если такой путь существует, обновить результат и продолжить поиск в верхней половине (left = mid + 1).
    • В противном случае --- в нижней половине (right = mid - 1).
  3. Итоговый результат --- максимальное допустимое значение mid.

Реализация на C++ (Двоичный поиск + BFS)

cpp 复制代码
#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;

struct Edge {
    int u, v, b;
    Edge(int u, int v, int b) : u(u), v(v), b(b) {}
};

bool hasPath(const vector<vector<Edge>>& graph, int n, int min_b) {
    vector<bool> visited(n+1, false);
    queue<int> q{{1}};
    visited[1] = true;
    
    while (!q.empty()) {
        int u = q.front();
        q.pop();
        if (u == n) return true;
        
        for (const Edge& e : graph[u]) {
            if (!visited[e.v] && e.b >= min_b) {
                visited[e.v] = true;
                q.push(e.v);
            }
        }
    }
    return false;
}

int main() {
    int n, m;
    cin >> n >> m;
    
    vector<vector<Edge>> graph(n+1);
    vector<int> bandwidths;
    
    for (int i = 0; i < m; ++i) {
        int u, v, b;
        cin >> u >> v >> b;
        graph[u].emplace_back(u, v, b);
        graph[v].emplace_back(v, u, b);
        bandwidths.push_back(b);
    }
    
    int low = 0, high = *max_element(bandwidths.begin(), bandwidths.end());
    int res = 0;
    
    while (low <= high) {
        int mid = low + (high - low)/2;
        if (hasPath(graph, n, mid)) {
            res = mid;
            low = mid + 1;
        } else {
            high = mid - 1;
        }
    }
    
    cout << res << endl;
    return 0;
}

Пояснение к коду

  • Структура Edge : Хранит информацию о ребре (узлы u, v и пропускную способность b).
  • Функция hasPath : Использует BFS для проверки существования пути с пропускной способностью всех ребер ≥ min_b.
  • Основная функция :
    1. Создает список смежности из входных данных.
    2. Использует двоичный поиск для определения максимальной допустимой минимальной пропускной способности.
    3. Выводит результат.

Анализ сложности

  • Время: O((n + m) log B), где B --- максимальная пропускная способность ребра.
  • Память: O(n + m) для хранения графа и очереди BFS.

Тестовый пример
Ввод:

cpp 复制代码
4 5
1 2 3
1 3 2
2 3 4
2 4 2
3 4 3

Вывод:

cpp 复制代码
3

Пояснение : Путь 1 → 2 → 3 → 4 имеет минимальную пропускную способность 3, что является оптимальным решением.

阿拉伯文版:

وصف المشكلة

آخر مسألة في مسابقة IOI لعام 1989 هي مسألة تقليدية لتحسين شبكة الاتصالات. إليك الوصف التفصيلي:

نظام تواصل يتكون من n عقدة (مرقمة من 1 إلى n)، حيث بعض العقد متصلة ببعض عبر خطوط اتصال ثنائية الاتجاه، لكل خط عرض بيانات ثابت. المهمة هي نقل البيانات من العقدة 1 إلى العقدة n على طول مسار بحيث يكون الحد الأدنى لعرض البيانات على طول المسار كبيرًا بقدر الإمكان. وضعت هذا الحد الأدنى العظمى لعرض البيانات.

تنسيق الإدخال

  • تحتوي السطر الأول على عددين صحيحين n و m، والتي تشير إلى عدد العقد وعدد خطوط الاتصال.
  • تحتوي الأسطر التالية m على ثلاثة أرقام صحيحة u و v و b، والتي تشير إلى وجود خط اتصال ثنائي الاتجاه بين العقد u و v بعرض بيانات b.

تنسيق الخرج

  • عدد صحيح واحد يمثل الحد الأدنى العظمى لعرض البيانات بين جميع المسارات من العقدة 1 إلى العقدة n.

المنهج

يمكن تحويل هذه المسألة إلى البحث عن أقصى مسار لإنتقاط، حيث يتم تعظيم الحد الأدنى لوزن الحافة على طول المسار. يتم تقديم نهجين فعالين:

الطريقة 1: أكبر شجرة تغطية

في أكبر شجرة تغطية، المسار بين أي عقدتين يحتوي على أعلى حد ممكن لحد أدنى وزن الحافة مقارنة بجميع المسارات الأخرى الممكنة.

خطوات الخوارزمية

  1. فرز جميع الحواف بترتيب تنازلي لفائضاتها.
  2. بناء أكبر شجرة تغطية باستخدام خوارزمية كروسكال.
  3. استخدام DFS/BFS على أكبر شجرة تغطية للعثور على المسار من العقدة 1 إلى العقدة n، متابعة الحد الأدنى لوزن الحافة على طول هذا المسار.

الطريقة 2: البحث الثنائي + BFS

خطوات الخوارزمية

  1. حدد نطاق البحث الثنائي: left = 0 (الحد الأدنى الممكن لعرض البيانات) و right = max(bandwidths) (أقصى عرض بيانات للحواف).
  2. لكل نقطة متوسطة mid في البحث الثنائي:
    • تحقق مما إذا كان هناك مسار من العقدة 1 إلى العقدة n حيث جميع الحواف لها عرض بيانات ≥ mid.
    • إذا كان يوجد مثل هذا المسار، قم بتحديث النتيجة والبحث في النصف الأعلى (left = mid + 1).
    • خلاف ذلك، ابحث في النصف السفلي (right = mid - 1).
  3. النتيجة النهائية هي mid الأكبر الممكن.

تنفيذ C++ (البحث الثنائي + BFS)

cpp 复制代码
#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;

struct Edge {
    int u, v, b;
    Edge(int u, int v, int b) : u(u), v(v), b(b) {}
};

bool hasPath(const vector<vector<Edge>>& graph, int n, int min_b) {
    vector<bool> visited(n+1, false);
    queue<int> q{{1}};
    visited[1] = true;
    
    while (!q.empty()) {
        int u = q.front();
        q.pop();
        if (u == n) return true;
        
        for (const Edge& e : graph[u]) {
            if (!visited[e.v] && e.b >= min_b) {
                visited[e.v] = true;
                q.push(e.v);
            }
        }
    }
    return false;
}

int main() {
    int n, m;
    cin >> n >> m;
    
    vector<vector<Edge>> graph(n+1);
    vector<int> bandwidths;
    
    for (int i = 0; i < m; ++i) {
        int u, v, b;
        cin >> u >> v >> b;
        graph[u].emplace_back(u, v, b);
        graph[v].emplace_back(v, u, b);
        bandwidths.push_back(b);
    }
    
    int low = 0, high = *max_element(bandwidths.begin(), bandwidths.end());
    int res = 0;
    
    while (low <= high) {
        int mid = low + (high - low)/2;
        if (hasPath(graph, n, mid)) {
            res = mid;
            low = mid + 1;
        } else {
            high = mid - 1;
        }
    }
    
    cout << res << endl;
    return 0;
}

شرح الكود

  • هيكل Edge : يخزن معلومات الحافة (العقد u, v وعرض البيانات b).
  • دالة hasPath : تستخدم BFS للتحقق مما إذا كان يوجد مسار صالح مع جميع الحواف ≥ min_b.
  • الدالة الرئيسية :
    1. بناء قائمة مجاورة من الإدخال.
    2. استخدام البحث الثنائي لتحديد أقصى حد أدنى ممكن لعرض البيانات.
    3. إخراج النتيجة.

تحليل التعقيد

  • الوقت: O((n + m) log B)، حيث B هو أقصى عرض بيانات للحدث.
  • ال공간: O(n + m) لتخزين الرسم وطابور BFS.

حالة الاختبار
مدخلات:

cpp 复制代码
4 5
1 2 3
1 3 2
2 3 4
2 4 2
3 4 3

إخراج:

cpp 复制代码
3

التوضيح : المسار 1 → 2 → 3 → 4 يحتوي على الحد الأدنى لعرض البيانات 3، وهو الحل الأمثل.

西班牙文版:

Descripción del problema

El último problema del IOI de 1989 es un clásico problema de optimización de redes de comunicación. Su descripción es la siguiente:

Dada una red de comunicación con n nodos (numerados del 1 al n), donde existen líneas de comunicación bidireccionales entre algunos nodos, cada una con un ancho de banda fijo. Se necesita transmitir datos desde el nodo 1 al nodo n, y se requiere encontrar la ruta de transmisión que maximice el ancho de banda mínimo de la ruta, y output este valor máximo de ancho de banda mínimo.

Formato de entrada

La primera línea contiene dos enteros n y m, que representan el número de nodos y el número de líneas

Las siguientes m líneas contienen tres enteros u, v, b cada una, indicando que existe una línea de comunicación con ancho de banda b entre los nodos u y v

Formato de salida

Un entero que representa el ancho de banda mínimo máximo en la ruta desde 1 hasta n

Ideas de resolución

Este problema se puede transformar en un problema de ruta de cuello de botella máximo, y las soluciones principales incluyen el método de árbol de expansión máximo y el método de búsqueda binaria + BFS/DFS.

Método 1: Árbol de expansión máximo

El peso mínimo de la ruta entre cualesquiera dos puntos en un árbol de expansión máximo es el ancho de banda mínimo máximo entre todos los posibles caminos.

Pasos del algoritmo

Ordenar las aristas por ancho de banda en orden descendente

Construir un árbol de expansión máximo usando el algoritmo de Kruskal

Encontrar la ruta desde 1 hasta n en el árbol generado usando DFS/BFS, y registrar el peso mínimo de las aristas

Método 2: Búsqueda binaria + BFS

Pasos del algoritmo

Determinar el rango de búsqueda binaria: límite izquierdo 0, límite derecho es el ancho de banda máximo de las aristas

Tomar el valor mid cada vez, y verificar si existe una ruta desde 1 hasta n que cumpla con que todos los anchos de banda de las aristas sean ≥ mid

Si existe, intentar con un mid mayor; 否则,intentar con un mid menor

El mid máximo viable obtenido finalmente es la solución

Implementación en C++ (búsqueda binaria + BFS)

cpp 复制代码
#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;

struct Edge {
    int u, v, b;
    Edge(int u, int v, int b) : u(u), v(v), b(b) {}
};

bool hasPath(const vector<vector<Edge>>& graph, int n, int min_b) {
    vector<bool> visited(n+1, false);
    queue<int> q{{1}};
    visited[1] = true;
    
    while (!q.empty()) {
        int u = q.front();
        q.pop();
        if (u == n) return true;
        
        for (const Edge& e : graph[u]) {
            if (!visited[e.v] && e.b >= min_b) {
                visited[e.v] = true;
                q.push(e.v);
            }
        }
    }
    return false;
}

int main() {
    int n, m;
    cin >> n >> m;
    
    vector<vector<Edge>> graph(n+1);
    vector<int> bandwidths;
    
    for (int i = 0; i < m; ++i) {
        int u, v, b;
        cin >> u >> v >> b;
        graph[u].emplace_back(u, v, b);
        graph[v].emplace_back(v, u, b);
        bandwidths.push_back(b);
    }
    
    int low = 0, high = *max_element(bandwidths.begin(), bandwidths.end());
    int res = 0;
    
    while (low <= high) {
        int mid = low + (high - low)/2;
        if (hasPath(graph, n, mid)) {
            res = mid;
            low = mid + 1;
        } else {
            high = mid - 1;
        }
    }
    
    cout << res << endl;
    return 0;
}

Explicación del código

  • La estructura Edge almacena información de las aristas

  • La función hasPath usa BFS para verificar si existe una ruta que cumpla con las condiciones

  • Función principal:

    Construir la lista de adyacencia

    Usar búsqueda binaria para determinar el ancho de banda mínimo máximo

    Output el resultado

Análisis de complejidad

  • Tiempo: O((n+m)logB)

  • Espacio: O(n+m)

Caso de prueba

Entrada:

cpp 复制代码
4 5
1 2 3
1 3 2
2 3 4
2 4 2
3 4 3

Salida:

cpp 复制代码
3

Explicación: La ruta 1→2→3→4 tiene un ancho de banda mínimo de 3, que es la solución óptima.

相关推荐
程序员编程指南几秒前
Qt 网络编程进阶:WebSocket 通信
c语言·网络·c++·qt·websocket
regret~2 小时前
【记录】C++生产者 / 消费者 案例
开发语言·c++
尘似鹤2 小时前
c++注意点(12)----设计模式(生成器)
c++·设计模式
m0_687399843 小时前
Ubuntu22 上,用C++ gSoap 创建一个简单的webservice
开发语言·c++
屁股割了还要学3 小时前
【C语言进阶】一篇文章教会你文件的读写
c语言·开发语言·数据结构·c++·学习·青少年编程
Shingmc33 小时前
【C++】二叉搜索数
开发语言·c++
洁可6 小时前
上位机程序开发基础介绍
c++·笔记
寒心雨梦6 小时前
本地preload hook案例
c++
滴水成川7 小时前
现代 C++ 开发工作流(VSCode / Cursor)
开发语言·c++·vscode·cursor
张同学的IT技术日记8 小时前
重构 MVC:让经典架构完美适配复杂智能系统的后端业务逻辑层(内附框架示例代码)
c++·后端·重构·架构·mvc·软件开发·工程应用