Skip to content
Related Articles

Related Articles

Improve Article
Save Article
Like Article

Find palindromic path of given length K in a complete Binary Weighted Graph

  • Last Updated : 26 Nov, 2021

Given a complete directed graph having N vertices, whose edges weighs ‘1’ or ‘0’, the task is to find a path of length exactly K which is a palindrome. Print “YES” if possible and then the path, otherwise print “NO“. 

Example: 

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.  To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

In case you wish to attend live classes with experts, please refer DSA Live Classes for Working Professionals and Competitive Programming Live for Students.

Input: N = 3, K = 4
edges[] =  {{{1, 2}, ‘1’}, {{1, 3}, ‘1’}, {{2, 1}, ‘1’}, {{2, 3}, ‘1’}, {{3, 1}, ‘0’}, {{3, 2}, ‘0’}}
Output
YES
2 1  2 1 2
Explanation



The path followed is “1111” which is palindrome.

Input: N = 2, K = 6
edges[] = { { 1, 2 }, ‘1’ }, { { 2, 1 }, ‘0’ } 
Output: NO

Approach: The above problem can be solved by considering different cases and constructing the respective answers. Follow the below steps to solve the problem:

  1. If K is odd:
    • There exists a palindromic path in every case if K is odd.
    • It can be constructed by selecting any two nodes and looping through them K times, For example, for  K = 5:  “00000”, “11111”, “10101”, “01010”.
  2. If K is even:
    • Now the problem can be divided into two cases:
      • If Two nodes (i, j) exists such that the weight of edge i->j is equal to the weight of edge j->i. Then the answer can be constructed by looping through them until path length K is achieved.
      • Otherwise, if there exist three different nodes (i, j, k) such that the weight of edge i->j is equal to the weight of edge j->k. Then these three nodes can be placed in the centre of the path, like …i->j->i->j->k->j->k…, to create an even length palindrome.
  3. Print the answer according to the above observation.

Below is the implementation of the above approach:

C++




// C++ implementation for the above approach
 
#include <bits/stdc++.h>
using namespace std;
 
// Function to print the left path
void printLeftPath(int i, int j, int K)
{
    if (K & 1) {
        // j->i->j->i->j->k->j->k->j
        for (int p = 0; p < K; p++) {
            if (p & 1) {
                cout << i << " ";
            }
            else {
                cout << j << " ";
            }
        }
    }
    else {
        // i->j->i->j->k->j->k
        for (int p = 0; p < K; p++) {
            if (p & 1) {
                cout << j << " ";
            }
            else {
                cout << i << " ";
            }
        }
    }
}
 
// Function to print the right path
void printRightPath(int j, int k, int K)
{
    if (K & 1) {
        // j->i->j->i->j->k->j->k->j
        for (int p = 0; p < K; p++) {
            if (p & 1) {
                cout << k << " ";
            }
            else {
                cout << j << " ";
            }
        }
    }
    else {
        // i->j->i->j->k->j->k
        for (int p = 0; p < K; p++) {
            if (p & 1) {
                cout << k << " ";
            }
            else {
                cout << j << " ";
            }
        }
    }
}
 
// Function to check that
// if there exists a palindromic path
// in a binary graph
void constructPalindromicPath(
    vector<pair<pair<int, int>, char> > edges,
    int n, int K)
{
    // Create adjacency matrix
    vector<vector<char> > adj(
        n + 1,
        vector<char>(n + 1));
    for (int i = 0; i < edges.size(); i++) {
        adj[edges[i]
                .first.first][edges[i]
                                  .first.second]
            = edges[i].second;
    }
 
    // If K is odd then
    // print the path directly by
    // choosing node 1 and 2 repeatedly
    if (K & 1) {
        cout << "YES" << endl;
        for (int i = 1; i <= K + 1; i++) {
            cout << (i & 1) + 1 << " ";
        }
        return;
    }
 
    // If K is even
    // Try to find an edge such that weight of
    // edge i->j and j->i is equal
    bool found = 0;
    int idx1, idx2;
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= n; j++) {
            if (i == j) {
                continue;
            }
            if (adj[i][j] == adj[j][i]) {
                // Same weight edges are found
                found = 1;
 
                // Store their indexes
                idx1 = i, idx2 = j;
            }
        }
    }
    if (found) {
        // Print the path
        cout << "YES" << endl;
        for (int i = 1; i <= K + 1; i++) {
            if (i & 1) {
                cout << idx1 << " ";
            }
            else {
                cout << idx2 << " ";
            }
        }
        return;
    }
 
    // If nodes i, j having equal weight
    // on edges i->j and j->i can not
    // be found then try to find
    // three nodes i, j, k such that
    // weights of edges i->j
    // and j->k are equal
    else {
 
        // To store edges with weight '0'
        vector<int> mp1[n + 1];
 
        // To store edges with weight '1'
        vector<int> mp2[n + 1];
 
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= n; j++) {
                if (i == j) {
                    continue;
                }
                if (adj[i][j] == '0') {
                    mp1[i].push_back(j);
                }
                else {
                    mp2[i].push_back(j);
                }
            }
        }
 
        // Try to find edges i->j and
        // j->k having weight 0
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= n; j++) {
                if (j == i) {
                    continue;
                }
                if (adj[i][j] == '0') {
                    if (mp1[j].size()) {
                        int k = mp1[j][0];
                        if (k == i || k == j) {
                            continue;
                        }
                        cout << "YES" << endl;
                        K -= 2;
                        K /= 2;
 
                        // Print left Path
                        printLeftPath(i, j, K);
 
                        // Print centre
                        cout << i << " "
                             << j << " " << k
                             << " ";
 
                        // Print right path
                        printRightPath(j, k, K);
                        return;
                    }
                }
            }
        }
 
        // Try to find edges i->j
        // and j->k which having
        // weight 1
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= n; j++) {
                if (j == i) {
                    continue;
                }
                if (adj[i][j] == '1') {
                    if (mp1[j].size()) {
                        int k = mp1[j][0];
                        // cout<<k;
                        if (k == i || k == j) {
                            continue;
                        }
                        cout << "YES" << endl;
                        K -= 2;
                        K /= 2;
                        printLeftPath(i, j, K);
                        cout << i << " "
                             << j << " " << k
                             << " ";
                        printRightPath(j, k, K);
                        return;
                    }
                }
            }
        }
    }
    cout << "NO";
}
 
// Driver Code
int main()
{
    int N = 3, K = 4;
    vector<pair<pair<int, int>, char> > edges
        = { { { 1, 2 }, '1' },
            { { 1, 3 }, '1' },
            { { 2, 1 }, '1' },
            { { 2, 3 }, '1' },
            { { 3, 1 }, '0' },
            { { 3, 2 }, '0' } };
 
    constructPalindromicPath(edges, N, K);
}


Python3




# Python implementation for the above approach
 
# Function to print the left path
def printLeftPath(i, j, K):
    if (K & 1):
        # j->i->j->i->j->k->j->k->j
        for p in range(0, K):
            if (p & 1):
                print(i, end=" ")
            else:
                print(j, end=" ")
 
    else:
        # i->j->i->j->k->j->k
        for p in range(K):
            if (p & 1):
                print(j, end=" ")
            else:
                print(i, end=" ")
 
 
# Function to print the right path
def printRightPath(j, k, K):
    if (K & 1):
        # j->i->j->i->j->k->j->k->j
        for p in range(K):
            if (p & 1):
                print(K, end=" ")
            else:
                print(j, end=" ")
    else:
        # i->j->i->j->k->j->k
        for p in range(K):
            if (p & 1):
                print(K, end=" ")
            else:
                print(j, end=" ")
 
 
# Function to check that
# if there exists a palindromic path
# in a binary graph
def constructPalindromicPath(edges, n, K):
    # Create adjacency matrix
    adj = [[0 for i in range(n + 1)] for i in range(n + 1)]
 
    for i in range(len(edges)):
        adj[edges[i][0][0]][edges[i][0][1]] = edges[i][1]
 
    # If K is odd then
    # print the path directly by
    # choosing node 1 and 2 repeatedly
    if (K & 1):
        print("YES")
        for i in range(1, K + 2):
            print((i & 1) + 1, end=" ")
        return
 
    # If K is even
    # Try to find an edge such that weight of
    # edge i->j and j->i is equal
    found = 0
    idx1 = None
    idx2 = None
 
    for i in range(1, n + 1):
        for j in range(1, n + 1):
            if (i == j):
                continue
 
            if (adj[i][j] == adj[j][i]):
                # Same weight edges are found
                found = 1
 
                # Store their indexes
                idx1 = i
                idx2 = j
 
    if (found):
        # Print the path
        print("YES")
        for i in range(1, K + 2):
            if (i & 1):
                print(idx1, end=" ")
            else:
                print(idx2, end=" ")
        return
 
    # If nodes i, j having equal weight
    # on edges i->j and j->i can not
    # be found then try to find
    # three nodes i, j, k such that
    # weights of edges i->j
    # and j->k are equal
    else:
 
        # To store edges with weight '0'
        mp1 = [[] for i in range*(n + 1)]
 
        # To store edges with weight '1'
        mp2 = [[] for i in range(n + 1)]
 
        for i in range(1, n + 1):
            for j in range(1, n + 1):
                if (i == j):
                    continue
 
                if (adj[i][j] == '0'):
                    mp1[i].push(j)
                else:
                    mp2[i].push(j)
 
        # Try to find edges i->j and
        # j->k having weight 0
        for i in range(1, n + 1):
            for j in range(1, n + 1):
                if (j == i):
                    continue
 
                if (adj[i][j] == '0'):
                    if (len(mp1[j])):
                        k = mp1[j][0]
                        if (k == i or k == j):
                            continue
 
                        print("YES")
                        K -= 2
                        K = k // 2
 
                        # Print left Path
                        printLeftPath(i, j, K)
 
                        # Print centre
                        print(f"{i} {j} {k}")
 
                        # Print right path
                        printRightPath(j, k, K)
                        return
 
        # Try to find edges i->j
        # and j->k which having
        # weight 1
        for i in range(1, n + 1):
            for j in range(1, n + 1):
                if (j == i):
                    continue
 
                if (adj[i][j] == '1'):
                    if (len(mp1[j])):
                        k = mp1[j][0]
                        # cout<<k;
                        if (k == i or k == j):
                            continue
 
                        print("YES")
                        K -= 2
                        K = k // 2
                        printLeftPath(i, j, K)
                        print(f"{i} {j} {k}")
                        printRightPath(j, k, K)
                        return
 
    print("NO")
 
 
# Driver Code
N = 3
K = 4
edges = [[[1, 2], '1'],
         [[1, 3], '1'],
         [[2, 1], '1'],
         [[2, 3], '1'],
         [[3, 1], '0'],
         [[3, 2], '0']]
 
constructPalindromicPath(edges, N, K)
 
# This code is contributed by gfgking.


Javascript




<script>
    // JavaScript implementation for the above approach
 
 
    // Function to print the left path
    const printLeftPath = (i, j, K) => {
        if (K & 1) {
            // j->i->j->i->j->k->j->k->j
            for (let p = 0; p < K; p++) {
                if (p & 1) {
                    document.write(`${i} `);
                }
                else {
                    document.write(`${j} `);
                }
            }
        }
        else {
            // i->j->i->j->k->j->k
            for (let p = 0; p < K; p++) {
                if (p & 1) {
                    document.write(`${j} `);
                }
                else {
                    document.write(`${i} `);
                }
            }
        }
    }
 
    // Function to print the right path
    const printRightPath = (j, k, K) => {
        if (K & 1) {
            // j->i->j->i->j->k->j->k->j
            for (let p = 0; p < K; p++) {
                if (p & 1) {
                    document.write(`${K} `);
                }
                else {
                    document.write(`${j} `);
                }
            }
        }
        else {
            // i->j->i->j->k->j->k
            for (let p = 0; p < K; p++) {
                if (p & 1) {
                    document.write(`${K} `);
                }
                else {
                    document.write(`${j} `);
                }
            }
        }
    }
 
    // Function to check that
    // if there exists a palindromic path
    // in a binary graph
    const constructPalindromicPath = (edges, n, K) => {
        // Create adjacency matrix
        let adj = new Array(n + 1).fill(0).map(() => new Array(n + 1).fill(0));
        for (let i = 0; i < edges.length; i++) {
            adj[edges[i][0][0]][edges[i][0][1]] = edges[i][1];
        }
 
        // If K is odd then
        // print the path directly by
        // choosing node 1 and 2 repeatedly
        if (K & 1) {
            document.write(`YES<br/>`);
            for (let i = 1; i <= K + 1; i++) {
                document.write(`${(i & 1) + 1} `);
            }
            return;
        }
 
        // If K is even
        // Try to find an edge such that weight of
        // edge i->j and j->i is equal
        let found = 0;
        let idx1, idx2;
        for (let i = 1; i <= n; i++) {
            for (let j = 1; j <= n; j++) {
                if (i == j) {
                    continue;
                }
                if (adj[i][j] == adj[j][i]) {
                    // Same weight edges are found
                    found = 1;
 
                    // Store their indexes
                    idx1 = i;
                    idx2 = j;
                }
            }
        }
        if (found) {
            // Print the path
            document.write(`YES<br/>`)
            for (let i = 1; i <= K + 1; i++) {
                if (i & 1) {
                    document.write(`${idx1} `);
                }
                else {
                    document.write(`${idx2} `);
                }
            }
            return;
        }
 
        // If nodes i, j having equal weight
        // on edges i->j and j->i can not
        // be found then try to find
        // three nodes i, j, k such that
        // weights of edges i->j
        // and j->k are equal
        else {
 
            // To store edges with weight '0'
            let mp1 = new Array(n + 1).fill([]);
 
            // To store edges with weight '1'
            let mp2 = new Array(n + 1).fill([]);
 
            for (let i = 1; i <= n; i++) {
                for (let j = 1; j <= n; j++) {
                    if (i == j) {
                        continue;
                    }
                    if (adj[i][j] == '0') {
                        mp1[i].push(j);
                    }
                    else {
                        mp2[i].push(j);
                    }
                }
            }
 
            // Try to find edges i->j and
            // j->k having weight 0
            for (let i = 1; i <= n; i++) {
                for (let j = 1; j <= n; j++) {
                    if (j == i) {
                        continue;
                    }
                    if (adj[i][j] == '0') {
                        if (mp1[j].size()) {
                            let k = mp1[j][0];
                            if (k == i || k == j) {
                                continue;
                            }
                            document.write(`YES<br/>`);
                            K -= 2;
                            K = parseInt(k / 2);
 
                            // Print left Path
                            printLeftPath(i, j, K);
 
                            // Print centre
                            document.write(`${i} ${j} ${k} `);
 
                            // Print right path
                            printRightPath(j, k, K);
                            return;
                        }
                    }
                }
            }
 
            // Try to find edges i->j
            // and j->k which having
            // weight 1
            for (let i = 1; i <= n; i++) {
                for (let j = 1; j <= n; j++) {
                    if (j == i) {
                        continue;
                    }
                    if (adj[i][j] == '1') {
                        if (mp1[j].length) {
                            let k = mp1[j][0];
                            // cout<<k;
                            if (k == i || k == j) {
                                continue;
                            }
                            document.write(`YES<br/>`);
                            K -= 2;
                            K = parseInt(k / 2);
                            printLeftPath(i, j, K);
                            document.write(`${i} ${j} ${k} `);
                            printRightPath(j, k, K);
                            return;
                        }
                    }
                }
            }
        }
        document.write("NO");
    }
 
    // Driver Code
    let N = 3, K = 4;
    let edges = [[[1, 2], '1'],
    [[1, 3], '1'],
    [[2, 1], '1'],
    [[2, 3], '1'],
    [[3, 1], '0'],
    [[3, 2], '0']];
 
    constructPalindromicPath(edges, N, K);
 
// This code is contributed by rakeshsahni.
</script>


Output

YES
2 1 2 1 2 

Time Complexity: O(N*N)
Auxiliary Space: O(N*N)




My Personal Notes arrow_drop_up
Recommended Articles
Page :