给定一个数组arr[][]由N个{L, R, V}形式的段组成,其中[L, R]表示在任何方向上速度为V的段,任务是检查是否可以分配所有线段的左或右方向,以便它们在很长一段时间后不会相交。
例子:
Input: arr[][] = {{5, 7, 2}, {4, 6, 1}, {1, 5, 2}, {6, 5, 1}}
Output: Yes
Explanation: Assign left direction to the first and second segments and right direction to the third and fourth segments.
Input: arr[][] = {{1, 2, 3}}
Output: Yes
方法:根据以下观察可以解决给定的问题:
- 情况一:当两段速度不同时:
- 这个想法是为两个段分配相同的方向。
- 因此,经过很长一段时间后,这些段将永远不会相交或重叠。有可能在这段时间之间,段的某处重叠。然后,最终一个细分市场将超过另一个细分市场。
- 情况 2 :当两个线段的速度相同,但在 t = 0 处不相交时:
- 这个想法是为它们分配相同的运动方向到两个部分。
- 由于它们的相对位置不会因相同的速度和相同的方向而改变,因此在无限时间之后,它们的相对位置将保持不变,不会重叠。
- 情况3 :当两个段的速度相同时,它们最初重叠/相交。
- 这个想法是为它们分配相反的运动方向。
以下示例说明了上述所有情况:
根据上述观察,想法是为所有重叠段创建一个图,并检查创建的图是否是二部图。如果创建的图是二部图,则可以为所有线段分配方向,使它们在很长一段时间后不相交。因此,打印“是” 。否则,打印“否” 。
请按照以下步骤解决问题:
- 从给定的数组arr[][]生成所有可能的不同元素对。如果任何一对段(arr[i], arr[j])重叠,则在它们之间添加无向边(i, j) 。
- 检查给定图对于[0, N – 1]范围内的所有可能节点是否是二部图。如果发现是真的,则打印“是” 。否则,打印“否” 。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Stores the details of the Segment
struct Node {
int L, R, V;
};
// Function to check whether the
// graph is bipartite or not
bool check(vector Adj[], int Src,
int N, bool visited[])
{
int color[N] = { 0 };
// Mark source node as visited
visited[Src] = true;
queue q;
// Push the source vertex in queue
q.push(Src);
while (!q.empty()) {
// Get the front of the queue
int u = q.front();
q.pop();
// Assign the color
// to the popped node
int Col = color[u];
// Traverse the adjacency
// list of the node u
for (int x : Adj[u]) {
// If any node is visited &
// a different colors has been
// assigned, then return false
if (visited[x] == true
&& color[x] == Col) {
return false;
}
else if (visited[x] == false) {
// Set visited[x]
visited[x] = true;
// Push the node x
// into the queue
q.push(x);
// Update color of node
color[x] = 1 - Col;
}
}
}
// If the graph is bipartite
return true;
}
// Function to add an edge
// between the nodes u and v
void addEdge(vector Adj[],
int u, int v)
{
Adj[u].push_back(v);
Adj[v].push_back(u);
}
// Function to check if the assignment
// of direction can be possible to all
// the segments, such that they do not
// intersect after a long period of time
void isPossible(struct Node Arr[], int N)
{
// Stores the adjacency list
// of the created graph
vector Adj[N];
// Generate all possible pairs
for (int i = 0; i < N - 1; i++) {
for (int j = i + 1; j < N; j++) {
// If segments do not overlap
if (Arr[i].R < Arr[j].L
|| Arr[i].L > Arr[j].R) {
continue;
}
// Otherwise, the segments overlap
else {
if (Arr[i].V == Arr[j].V) {
// If both segments have
// same speed, then add an edge
addEdge(Adj, i, j);
}
}
}
}
// Keep the track of visited nodes
bool visited[N] = { false };
// Iterate for all possible nodes
for (int i = 0; i < N; i++) {
if (visited[i] == false
&& Adj[i].size() > 0) {
// Check whether graph is
// bipartite or not
if (check(Adj, i, N, visited)
== false) {
cout << "No";
return;
}
}
}
// If the graph is bipartite
cout << "Yes";
}
// Driver Code
int main()
{
struct Node arr[] = {
{ 5, 7, 2 }, { 4, 6, 1 },
{ 1, 5, 2 }, { 6, 5, 1 }
};
int N = sizeof(arr) / sizeof(arr[0]);
isPossible(arr, N);
return 0;
}
Java
// Java program for the above approach
import java.io.*;
import java.lang.*;
import java.util.*;
class GFG{
// Stores the details of the Segment
static class Node
{
int L, R, V;
Node(int L, int R, int V)
{
this.L = L;
this.R = R;
this.V = V;
}
}
// Function to check whether the
// graph is bipartite or not
static boolean check(ArrayList Adj[], int Src,
int N, boolean visited[])
{
int color[] = new int[N];
// Mark source node as visited
visited[Src] = true;
ArrayDeque q = new ArrayDeque<>();
// Push the source vertex in queue
q.addLast(Src);
while (!q.isEmpty())
{
// Get the front of the queue
int u = q.removeFirst();
// Assign the color
// to the popped node
int Col = color[u];
// Traverse the adjacency
// list of the node u
for(int x : Adj[u])
{
// If any node is visited &
// a different colors has been
// assigned, then return false
if (visited[x] == true && color[x] == Col)
{
return false;
}
else if (visited[x] == false)
{
// Set visited[x]
visited[x] = true;
// Push the node x
// into the queue
q.addLast(x);
// Update color of node
color[x] = 1 - Col;
}
}
}
// If the graph is bipartite
return true;
}
// Function to add an edge
// between the nodes u and v
static void addEdge(ArrayList Adj[], int u,
int v)
{
Adj[u].add(v);
Adj[v].add(u);
}
// Function to check if the assignment
// of direction can be possible to all
// the segments, such that they do not
// intersect after a long period of time
static void isPossible(Node Arr[], int N)
{
// Stores the adjacency list
// of the created graph
@SuppressWarnings("unchecked")
ArrayList [] Adj = (ArrayList[])new ArrayList[N];
// Initialize
for(int i = 0; i < N; i++)
Adj[i] = new ArrayList<>();
// Generate all possible pairs
for(int i = 0; i < N - 1; i++)
{
for(int j = i + 1; j < N; j++)
{
// If segments do not overlap
if (Arr[i].R < Arr[j].L ||
Arr[i].L > Arr[j].R)
{
continue;
}
// Otherwise, the segments overlap
else
{
if (Arr[i].V == Arr[j].V)
{
// If both segments have
// same speed, then add an edge
addEdge(Adj, i, j);
}
}
}
}
// Keep the track of visited nodes
boolean visited[] = new boolean[N];
// Iterate for all possible nodes
for(int i = 0; i < N; i++)
{
if (visited[i] == false && Adj[i].size() > 0)
{
// Check whether graph is
// bipartite or not
if (check(Adj, i, N, visited) == false)
{
System.out.println("No");
return;
}
}
}
// If the graph is bipartite
System.out.println("Yes");
}
// Driver Code
public static void main(String[] args)
{
Node arr[] = { new Node(5, 7, 2), new Node(4, 6, 1),
new Node(1, 5, 2), new Node(6, 5, 1) };
int N = arr.length;
isPossible(arr, N);
}
}
// This code is contributed by Kingash
Python3
# Python3 program for the above approach
from collections import deque
# Function to check whether the
# graph is bipartite or not
def check(Adj, Src, N, visited):
color = [0] * N
# Mark source node as visited
visited = [True] * Src
q = deque()
# Push the source vertex in queue
q.append(Src)
while (len(q) > 0):
# Get the front of the queue
u = q.popleft()
# q.pop()
# Assign the color
# to the popped node
Col = color[u]
# Traverse the adjacency
# list of the node u
for x in Adj[u]:
# If any node is visited &
# a different colors has been
# assigned, then return false
if (visited[x] == True and
color[x] == Col):
return False
elif (visited[x] == False):
# Set visited[x]
visited[x] = True
# Push the node x
# into the queue
q.append(x)
# Update color of node
color[x] = 1 - Col
# If the graph is bipartite
return True
# Function to add an edge
# between the nodes u and v
def addEdge(Adj, u, v):
Adj[u].append(v)
Adj[v].append(u)
return Adj
# Function to check if the assignment
# of direction can be possible to all
# the segments, such that they do not
# intersect after a long period of time
def isPossible(Arr, N):
# Stores the adjacency list
# of the created graph
Adj = [[] for i in range(N)]
# Generate all possible pairs
for i in range(N - 1):
for j in range(i + 1, N):
# If segments do not overlap
if (Arr[i][0] < Arr[j][1] or
Arr[i][1] > Arr[j][0]):
continue
# Otherwise, the segments overlap
else:
if (Arr[i][2] == Arr[j][2]):
# If both segments have
# same speed, then add an edge
Adj = addEdge(Adj, i, j)
# Keep the track of visited nodes
visited = [False] * N
# Iterate for all possible nodes
for i in range(N):
if (visited[i] == False and len(Adj[i]) > 0):
# Check whether graph is
# bipartite or not
if (check(Adj, i, N, visited) == False):
print ("No")
return
# If the graph is bipartite
print ("Yes")
# Driver Code
if __name__ == '__main__':
arr = [ [ 5, 7, 2 ], [ 4, 6, 1 ],
[ 1, 5, 2 ], [ 6, 5, 1 ] ]
N = len(arr)
isPossible(arr, N)
# This code is contributed by mohit kumar 29
C#
// C# program for the above approach
using System;
using System.Collections.Generic;
class GFG{
// Stores the details of the Segment
class Node
{
public int L, R, V;
};
static Node newNode(int L, int R, int V)
{
Node temp = new Node();
temp.L = L;
temp.R = R;
temp.V = V;
return temp;
}
// Function to check whether the
// graph is bipartite or not
static bool check(List []Adj, int Src,
int N, bool []visited)
{
int []color = new int[N];
// Mark source node as visited
visited[Src] = true;
Queue q = new Queue();
// Push the source vertex in queue
q.Enqueue(Src);
while (q.Count > 0)
{
// Get the front of the queue
int u = q.Peek();
q.Dequeue();
// Assign the color
// to the popped node
int Col = color[u];
// Traverse the adjacency
// list of the node u
foreach (int x in Adj[u])
{
// If any node is visited &
// a different colors has been
// assigned, then return false
if (visited[x] == true &&
color[x] == Col)
{
return false;
}
else if (visited[x] == false)
{
// Set visited[x]
visited[x] = true;
// Push the node x
// into the queue
q.Enqueue(x);
// Update color of node
color[x] = 1 - Col;
}
}
}
// If the graph is bipartite
return true;
}
// Function to add an edge
// between the nodes u and v
static void addEdge(List []Adj, int u, int v)
{
Adj[u].Add(v);
Adj[v].Add(u);
}
// Function to check if the assignment
// of direction can be possible to all
// the segments, such that they do not
// intersect after a long period of time
static void isPossible(Node []Arr, int N)
{
// Stores the adjacency list
// of the created graph
List [] Adj = new List[N];
// Initialize
for(int i = 0; i < N; i++)
Adj[i] = new List();
// Generate all possible pairs
for(int i = 0; i < N - 1; i++)
{
for(int j = i + 1; j < N; j++)
{
// If segments do not overlap
if (Arr[i].R < Arr[j].L ||
Arr[i].L > Arr[j].R)
{
continue;
}
// Otherwise, the segments overlap
else
{
if (Arr[i].V == Arr[j].V)
{
// If both segments have
// same speed, then add an edge
addEdge(Adj, i, j);
}
}
}
}
// Keep the track of visited nodes
bool []visited = new bool[N];
// Iterate for all possible nodes
for(int i = 0; i < N; i++)
{
if (visited[i] == false && Adj[i].Count > 0)
{
// Check whether graph is
// bipartite or not
if (check(Adj, i, N, visited) == false)
{
Console.Write("No");
return;
}
}
}
// If the graph is bipartite
Console.Write("Yes");
}
// Driver Code
public static void Main()
{
Node []arr = { newNode(5, 7, 2), newNode(4, 6, 1),
newNode(1, 5, 2), newNode(6, 5, 1) };
int N = arr.Length;
isPossible(arr, N);
}
}
// This code is contributed by SURENDRA_GANGWAR
Javascript
输出:
Yes
时间复杂度: O(N 2 )
辅助空间: O(N 2 )
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。