Submission #1324012

#TimeUsernameProblemLanguageResultExecution timeMemory
1324012sh_qaxxorov_571Dreaming (IOI13_dreaming)C++20
100 / 100
87 ms16160 KiB
#include "dreaming.h"
#include <vector>
#include <algorithm>
#include <queue>

using namespace std;

const int INF = 2e9;
vector<pair<int, int>> adj[100005];
bool visited[100005];
vector<int> nodes;

void dfs_find_nodes(int u) {
    visited[u] = true;
    nodes.push_back(u);
    for (auto& edge : adj[u]) {
        if (!visited[edge.first]) dfs_find_nodes(edge.first);
    }
}

// Eng uzoq masofani topish uchun yordamchi BFS
pair<int, int> bfs(int start, int n_limit, vector<int>& d_out) {
    for (int node : nodes) d_out[node] = -1;
    queue<int> q;
    q.push(start);
    d_out[start] = 0;
    int farthest_node = start;
    
    while (!q.empty()) {
        int u = q.front(); q.pop();
        if (d_out[u] > d_out[farthest_node]) farthest_node = u;
        for (auto& edge : adj[u]) {
            if (d_out[edge.first] == -1) {
                d_out[edge.first] = d_out[u] + edge.second;
                q.push(edge.first);
            }
        }
    }
    return {farthest_node, d_out[farthest_node]};
}

int travelTime(int N, int M, int L, int A[], int B[], int T[]) {
    for (int i = 0; i < M; i++) {
        adj[A[i]].push_back({B[i], T[i]});
        adj[B[i]].push_back({A[i], T[i]});
    }

    vector<int> radii;
    int max_diameter = 0;
    vector<int> dist1(N), dist2(N);

    for (int i = 0; i < N; i++) {
        if (!visited[i]) {
            nodes.clear();
            dfs_find_nodes(i);
            
            // Diametrni topish: 1-BFS eng chekka uchi u ni topadi
            pair<int, int> u = bfs(i, N, dist1);
            // 2-BFS u dan eng chekka v ni topadi
            pair<int, int> v = bfs(u.first, N, dist1);
            // 3-BFS v dan qaytib distlarni hisoblaydi
            bfs(v.first, N, dist2);

            max_diameter = max(max_diameter, v.second);
            
            // Shu daraxtning radiusini (minimal maksimal masofa) topamiz
            int min_max_dist = INF;
            for (int node : nodes) {
                min_max_dist = min(min_max_dist, max(dist1[node], dist2[node]));
            }
            radii.push_back(min_max_dist);
        }
    }

    sort(radii.rbegin(), radii.rend());

    if (radii.size() >= 2) {
        max_diameter = max(max_diameter, radii[0] + L + radii[1]);
    }
    if (radii.size() >= 3) {
        max_diameter = max(max_diameter, radii[1] + 2 * L + radii[2]);
    }

    return max_diameter;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...