Orig Description
G: DAG Trio / DAG Trio
This problem is the same setting as D: DAG Trio (Easy) except for the constraints.
Prologue
My little brother has been muttering "dag torio" recently.
Worried, I looked it up and found that in his class, $k$-DAG (a directed graph in which removing $k$ edges makes the number of connected components $k$, and all of them are DAG) is popular, and 3-DAG is called DAG trio.
To be respected by my brother, I decided to make a program that determines whether a given graph is DAG trio or not.
Problem Statement
Given a directed graph with $N$ vertices and $M$ edges.
Each vertex is numbered from $1$ to $N$.
Each directed edge is numbered from $1$ to $M$.
Directed edge $i$ goes from vertex $a_i$ to vertex $b_i$.
The graph is connected and simple (there is a path between any two vertices when ignoring the direction of edges, and there are no self-loops or multiple edges).
If the given graph is DAG trio, output "YES", otherwise output "NO".
Input
$N \ M$
$a_1 \ b_1$
$a_2 \ b_2$
$\vdots$
$a_M \ b_M$
Constraints
$3 \le N \le 500$
$\max(3, N−1) \le M \le 30000$
$1 \le a_i, b_i \le N$
The graph is connected when ignoring the direction of edges.
$a_i \neq b_i$ for all $i$.
$\{a_i, b_i\} \neq \{a_j, b_j\}$ for all $i \neq j$.
Output
Output "YES" or "NO" in a single line.
Sample
Sample Input 1
3 3
1 2
2 3
3 1
Sample Output 1
YES
Sample Input 2
6 7
1 2
2 3
4 3
4 5
5 6
6 4
3 6
Sample Output 2
YES
Sample Input 3
7 10
4 2
4 7
4 6
2 7
2 5
2 1
5 6
1 3
6 3
4 3
Sample Output 3
NO
Sample Input 4
4 4
1 2
3 2
4 3
2 4
Sample Output 4
YES
Sample Input 5
8 9
5 1
3 8
1 2
4 8
4 7
7 5
6 5
3 2
4 2
Sample Output 5
YES
Extracted Specification
An integer N (3 ≤ N ≤ 500), representing some quantity or size.
An integer M (max(3, N−1) ≤ M ≤ 30000), representing some quantity or size.
A list of M pairs of integers, where each integer in the pair is between 1 and N.
### Example Input:
```
3 3
1 2
2 3
3 1
```
### Function Signature:
Write a function f(N, M, edges) that takes in the input.
def f(N: int, M: int, edges: List[Tuple[int, int]]):
'''
N: an integer
M: an integer
edges: a list of tuples, each containing two integers
'''
Test Case Generator
Sure! Here is a Python function to generate test cases for the "DAG Trio" problem:
```python
import random
def generate_dag_trio_test_case():
N = random.randint(3, 500)
M = random.randint(max(3, N-1), 30000)
edges = set()
while len(edges) < M:
a = random.randint(1, N)
b = random.randint(1, N)
if a != b and (a, b) not in edges and (b, a) not in edges:
edges.add((a, b))
edges = list(edges)
random.shuffle(edges)
test_case = f"{N} {M}\n"
for a, b in edges:
test_case += f"{a} {b}\n"
return test_case.strip()
# Example usage:
print(generate_dag_trio_test_case())
```
### Explanation:
1. **Vertices and Edges Count:**
- `N` is chosen randomly between 3 and 500.
- `M` is chosen randomly between the maximum of 3 and \(N-1\) to 30000.
2. **Edges Generation:**
- A set `edges` is used to store unique edges.
- Random edges `(a, b)` are generated ensuring:
- `a` is not equal to `b` (no self-loops).
- Each edge `(a, b)` is unique and not already in the set (no multiple edges).
- Ensuring the graph is simple and connected (in practice, this random method combined with the constraints helps generate a connected graph).
3. **Output Format:**
- The test case is returned as a formatted string where:
- The first line is `N M`.
- Each subsequent line represents an edge `a b`.
This generator will help create randomized test cases suitable for the "DAG Trio" problem while respecting the constraints provided.
Extract Arguments
def extract_arguments(fh):
N, M = map(int, fh.readline().strip().split())
edges = [tuple(map(int, fh.readline().strip().split())) for _ in range(M)]
return N, M, edges
# if __name__ == "__main__":
# input_path = sys.argv[1]
# with open(input_path, 'r') as fh:
# N, M, edges = extract_arguments(fh)
# f(N, M, edges)