Fading Coder

One Final Commit for the Last Sprint

Home > Tech > Content

Optimizing Graph Traversal and Array Manipulation Algorithms

Tech May 12 2

Cycle Detection and Degree Validation

Determining whether a graph contains a cycle can be efficiently achieved using a Disjoint Set Union (DSU) structure. When merging two nodes, if they already share the same root, a cycle exists. Additionally, validating node degrees ensures structural integrity.

#include <iostream>
#include <vector>
#include <numeric>

using namespace std;

const int MAX_NODES = 100005;
int parent[MAX_NODES];
int degree[MAX_NODES];
bool cycleFound = false;

int getRoot(int node) {
    if (parent[node] != node) {
        return getRoot(parent[node]);
    }
    return node;
}

int main() {
    int n, m;
    if (!(cin >> n >> m)) return 0;

    for (int i = 0; i <= n; ++i) {
        degree[i] = 2;
        parent[i] = i;
    }

    for (int i = 0; i < m; ++i) {
        int u, v;
        cin >> u >> v;
        int rootU = getRoot(u);
        int rootV = getRoot(v);

        if (rootU == rootV) {
            cout << "No" << endl;
            return 0;
        }
        
        parent[rootU] = rootV;
        degree[u]--;
        degree[v]--;
    }

    for (int i = 1; i <= n; ++i) {
        if (degree[i] < 0) {
            cout << "No" << endl;
            cycleFound = true;
            break;
        }
    }

    if (!cycleFound) {
        cout << "Yes" << endl;
    }

    return 0;
}

Counting Valid Triangles in a Dataset

To count the number of valid triangles formed by lengths in an array, one must satisfy the triangle inequality theorem: the sum of any two sides must exceed the third. A brute-force approach checks all triplets, but sorting the array allows for optimization using binary search or two pointers.

Optimized Approach with Binary Search

By sorting the lengths in descending order, for any pair (a, b), we search for the largest (c) such that (b + c > a).

#include <iostream>
#include <algorithm>
#include <vector>

using namespace std;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int n;
    cin >> n;
    vector<int> lengths(n);

    for (int i = 0; i < n; ++i) {
        cin >> lengths[i];
    }

    sort(lengths.begin(), lengths.end(), greater<int>());

    long long validCount = 0;
    for (int i = 0; i < n - 2; ++i) {
        for (int j = i + 1; j < n - 1; ++j) {
            int left = j + 1;
            int right = n - 1;
            int boundary = -1;

            while (left <= right) {
                int mid = left + (right - left) / 2;
                if (lengths[i] < lengths[j] + lengths[mid]) {
                    boundary = mid;
                    left = mid + 1;
                } else {
                    right = mid - 1;
                }
            }

            if (boundary != -1) {
                validCount += (boundary - (j + 1) + 1);
            }
        }
    }

    cout << validCount << endl;
    return 0;
}

Extracting Cycles in Functional Graphs

In a functional graph where each node points to exact one other node, a cycle is guaranteed. The goal is to identify the nodes forming this cycle. We traverse the path until a visited node is encountered, then isolate the loop segment.

#include <iostream>
#include <vector>

using namespace std;

int main() {
    int n;
    cin >> n;
    
    vector<int> nextNode(n + 1);
    for (int i = 1; i <= n; ++i) {
        cin >> nextNode[i];
    }

    vector<int> visited(n + 1, 0);
    vector<int> path;
    int current = 1;

    while (visited[current] == 0) {
        visited[current] = 1;
        path.push_back(current);
        current = nextNode[current];
    }

    vector<int> cycleNodes;
    bool inCycle = false;
    
    for (int node : path) {
        if (node == current) {
            inCycle = true;
        }
        if (inCycle) {
            cycleNodes.push_back(node);
        }
    }

    cout << cycleNodes.size() << endl;
    for (int node : cycleNodes) {
        cout << node << " ";
    }
    cout << endl;

    return 0;
}

Validating Non-Decreasing Sequences under Operations

When transforming an array into a non-decreasing sequence using specific index-based operations, parity plays a crucial role. If the array length is even, its generally possible to satisfy the condition. For odd lengths, we must verify constraints backwards from the end of the array.

#include <iostream>
#include <vector>

using namespace std;

using ll = long long;

void solve() {
    int n;
    cin >> n;
    vector<ll> arr(n + 1);
    for (int i = 1; i <= n; ++i) {
        cin >> arr[i];
    }

    if (n % 2 == 0) {
        cout << "YES\n";
        return;
    }

    ll offset = 0;
    bool possible = true;
    for (int i = n; i >= 2; --i) {
        if (arr[i] + offset < arr[i - 1]) {
            possible = false;
            break;
        }
        if (i % 2 != 0) {
            offset += (arr[i] - arr[i - 1] + offset) / (i - 1);
        }
    }

    if (possible) {
        cout << "YES\n";
    } else {
        cout << "NO\n";
    }
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int t;
    cin >> t;
    while (t--) {
        solve();
    }
    return 0;
}

Comparative Array Analysis

Comparing two arrays involves checking specific adjacency conditions. Special handling is required for small input sizes. The logic verifies if elements match directly or via neighbors.

#include <iostream>
#include <vector>

using namespace std;

using ll = long long;

void runTest() {
    int n;
    cin >> n;
    vector<ll> source(n + 2, 0);
    vector<ll> target(n + 2, 0);

    for (int i = 1; i <= n; ++i) cin >> source[i];
    for (int i = 1; i <= n; ++i) cin >> target[i];

    int result = -1;
    if (n > 2) {
        result = 2;
    }

    for (int i = 1; i <= n; ++i) {
        bool match = (i > 1 && i < n && target[i] == source[i]) || 
                     (target[i] == source[i - 1]) || 
                     (target[i] == source[i + 1]);
        if (match) {
            result = 1;
        }
    }

    cout << result << endl;
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int t;
    cin >> t;
    while (t--) {
        runTest();
    }
    return 0;
}

Greedy Allocation with Neighbor Constraints

Maximizing the sum of values placed between numbers requires a greedy strategy. Values are allocated to the left first, then the right, ensuring the sum of neighbors does not exceed the current limit minus one.

#include <iostream>
#include <algorithm>
#include <vector>

using namespace std;

using ll = long long;

int main() {
    int n;
    cin >> n;
    vector<ll> limits(n);
    for (int i = 0; i < n; ++i) {
        cin >> limits[i];
    }

    ll totalSum = 0;
    ll consecutiveCount = 0;
    ll minVal = 2e10;

    for (int i = 0; i < n; ++i) {
        if (limits[i] == 1) {
            consecutiveCount = 0;
            minVal = 2e10;
        } else {
            if (i == 0 || i == n - 1) continue;
            
            consecutiveCount++;
            if (consecutiveCount <= 2) {
                minVal = min(minVal, limits[i]);
            }
            
            if (consecutiveCount >= 2) {
                ll k = min((minVal - 1), (limits[i] - 1));
                totalSum += k;
                minVal = limits[i] - k;
            }
        }
    }

    if (n > 0) {
        if (limits[0] != 1) totalSum += limits[0] - 1;
        if (limits[n - 1] != 1) totalSum += limits[n - 1] - 1;
    }
    
    if (n == 1) {
        totalSum = limits[0] - 1;
    }

    cout << totalSum << endl;
    return 0;
}
Tags: C++

Related Articles

Understanding Strong and Weak References in Java

Strong References Strong reference are the most prevalent type of object referencing in Java. When an object has a strong reference pointing to it, the garbage collector will not reclaim its memory. F...

Comprehensive Guide to SSTI Explained with Payload Bypass Techniques

Introduction Server-Side Template Injection (SSTI) is a vulnerability in web applications where user input is improper handled within the template engine and executed on the server. This exploit can r...

Implement Image Upload Functionality for Django Integrated TinyMCE Editor

Django’s Admin panel is highly user-friendly, and pairing it with TinyMCE, an effective rich text editor, simplifies content management significantly. Combining the two is particular useful for bloggi...

Leave a Comment

Anonymous

◎Feel free to join the discussion and share your thoughts.