// C++ program for the above approach
#include <bits/stdc++.h>
using namespace std;
// Recursive function to find all the
// nodes that are part of the cycle
void findNodesinCycle(int u, bool* vis,
int* prev,
vector<int> adj[],
vector<int>& inCycle)
{
// Mark current node as visited
vis[u] = true;
for (int v : adj[u]) {
// If node v is not visited
if (!vis[v]) {
prev[v] = u;
// Recursively find cycle
findNodesinCycle(v, vis, prev,
adj, inCycle);
// If cycle is detected then
// return the previous node
if (!inCycle.empty())
return;
}
// If node is already visited
// and not equal to prev[u]
else if (v != prev[u]) {
int curr = u;
inCycle.push_back(curr);
// Backtrack all vertices
// that are part of cycle
// and store them in inCycle
while (curr != v) {
curr = prev[curr];
inCycle.push_back(curr);
}
// As the cycle is detected
// return the previous node
return;
}
}
}
// Function to add the value of each
// node which is not part of the cycle
// to its nearest node in the cycle
int sumOfnonCycleNodes(
int u, vector<int> adj[],
vector<int> inCycle, bool* vis,
int arr[])
{
// Mark the current node as visited
vis[u] = true;
// Stores the value of required sum
int sum = 0;
for (int v : adj[u]) {
// If v is not already visited
// and not present in inCycle
if (!vis[v]
&& find(inCycle.begin(),
inCycle.end(), v)
== inCycle.end()) {
// Add to sum and call the
// function recursively
sum += (arr[v - 1]
+ sumOfnonCycleNodes(
v, adj, inCycle,
vis, arr));
}
}
// Return the value of sum
return sum;
}
// Function that add the edges
// to the graph
void addEdge(vector<int> adj[],
int u, int v)
{
adj[u].push_back(v);
adj[v].push_back(u);
}
// Utility Function to check if the cycle
// can be divided into two same sum
bool isBreakingPossible(vector<int> adj[],
int arr[], int N)
{
// Stores all the nodes that are
// part of the cycle
vector<int> inCycle;
// Array to check if a node is
// already visited or not
bool vis[N + 1];
// Initialize vis to false
memset(vis, false, sizeof vis);
// Array to store the previous node
// of the current node
int prev[N + 1];
// Initialize prev to 0
memset(prev, 0, sizeof prev);
// Recursive function call
findNodesinCycle(1, vis, prev,
adj, inCycle);
memset(vis, false, sizeof vis);
// Update value of each inCycle
// node
for (int u : inCycle) {
// Add sum of values of all
// required node to current
// inCycle node value
arr[u - 1] += sumOfnonCycleNodes(
u, adj, inCycle, vis, arr);
}
// Stores total sum of values of
// all nodes present in inCycle
int tot_sum = 0;
// Find the total required sum
for (int node : inCycle) {
tot_sum += arr[node - 1];
}
// If value of tot_sum is odd
// then return false
if (tot_sum % 2 != 0)
return false;
int req_sum = tot_sum / 2;
// Create an empty map
unordered_map<int, int> map;
// Initialise map[0]
map[0] = -1;
// Maintain the sum of values of
// nodes so far
int curr_sum = 0;
for (int i = 0; i < inCycle.size(); i++) {
// Add the current node value
// to curr_sum
curr_sum += arr[inCycle[i] - 1];
// If curr_sum - req_sum in map
// then there is a subarray of
// nodes with sum of their values
// equal to req_sum
if (map.find(curr_sum - req_sum)
!= map.end()) {
return true;
}
map[curr_sum] = i;
}
// If no such subarray exists
return false;
}
// Function to check if the cycle can
// be divided into two same sum
void checkCycleDivided(int edges[][2],
int arr[],
int N)
{
vector<int> adj[N + 1];
// Traverse the given edges
for (int i = 0; i < N; i++) {
int u = edges[i][0];
int v = edges[i][1];
// Add the edges
addEdge(adj, u, v);
}
// Print the result
cout << (isBreakingPossible(
adj, arr, N)
? "Yes"
: "No");
}
// Driver Code
int main()
{
int N = 10;
int edges[][2] = { { 1, 2 }, { 1, 5 }, { 1, 3 }, { 2, 6 }, { 2, 7 }, { 2, 4 }, { 4, 8 }, { 4, 3 }, { 3, 9 }, { 9, 10 } };
int arr[] = { 4, 2, 3, 3, 1,
2, 6, 2, 2, 5 };
// Function Call
checkCycleDivided(edges, arr, N);
return 0;
}