Problem p04010 - Generation 2

Orig Description

Score : 2200 points
Problem StatementYou are given an undirected graph with N vertices and M edges.
Here, N-1≤M≤N holds and the graph is connected.
There are no self-loops or multiple edges in this graph.
The vertices are numbered 1 through N, and the edges are numbered 1 through M.
Edge i connects vertices a_i and b_i.
The color of each vertex can be either white or black.
Initially, all the vertices are white.
Snuke is trying to turn all the vertices black by performing the following operation some number of times:
Select a pair of adjacent vertices with the same color, and invert the colors of those vertices. That is, if the vertices are both white, then turn them black, and vice versa.
Determine if it is possible to turn all the vertices black. If the answer is positive, find the minimum number of times the operation needs to be performed in order to achieve the objective.
Constraints
2≤N≤10^5
N-1≤M≤N
1≤a_i,b_i≤N
There are no self-loops or multiple edges in the given graph.
The given graph is connected.
Partial Score
In the test set worth 1500 points, M=N-1.
InputThe input is given from Standard Input in the following format:
N M
a_1 b_1
a_2 b_2
:
a_M b_M
OutputIf it is possible to turn all the vertices black, print the minimum number of times the operation needs to be performed in order to achieve the objective.
Otherwise, print -1 instead.
Sample Input 16 5
1 2
1 3
1 4
2 5
2 6
Sample Output 15
For example, it is possible to perform the operations as shown in the following diagram:
Sample Input 23 2
1 2
2 3
Sample Output 2-1
It is not possible to turn all the vertices black.
Sample Input 34 4
1 2
2 3
3 4
4 1
Sample Output 32
This case is not included in the test set for the partial score.
Sample Input 46 6
1 2
2 3
3 1
1 4
1 5
1 6
Sample Output 47
This case is not included in the test set for the partial score.

Extracted Specification

An integer N (2 ≤ N ≤ 10^5), representing some quantity or size.
An integer M (N-1 ≤ M ≤ N), representing another quantity or size.
M pairs of integers (a_i, b_i) (1 ≤ a_i, b_i ≤ N), representing connections or relationships between items.

### Example Input:

```
6 5
1 2
1 3
1 4
2 5
2 6
```

### Function Signature:
Write a function f(N, M, edges) that takes in the input.
```python
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, let's write a test case generator for the given graph problem. The generator will create a connected undirected graph with \( N \) vertices and \( M \) edges, where \( N-1 \leq M \leq N \). Here is the Python code for generating such test cases:

```python
import random
import sys

def generate_tree(N):
    """ Generate a random tree with N vertices. """
    edges = []
    for i in range(2, N + 1):
        edges.append((i, random.randint(1, i - 1)))
    return edges

def generate_additional_edges(N, M, tree_edges):
    """ Generate (M - (N - 1)) additional edges to ensure the graph has exactly M edges. """
    additional_edges = []
    existing_edges = set(tree_edges)
    while len(additional_edges) < (M - (N - 1)):
        u = random.randint(1, N)
        v = random.randint(1, N)
        if u != v and (u, v) not in existing_edges and (v, u) not in existing_edges:
            existing_edges.add((u, v))
            additional_edges.append((u, v))
    return additional_edges

def tcgen():
    N = random.randint(2, 10**5)
    M = random.randint(N - 1, N)
    
    tree_edges = generate_tree(N)
    additional_edges = generate_additional_edges(N, M, tree_edges)
    edges = tree_edges + additional_edges
    
    # Shuffle the edges to make the input less predictable
    random.shuffle(edges)
    
    return N, M, edges

def print_test_case(N, M, edges):
    print(N, M)
    for edge in edges:
        print(edge[0], edge[1])

# Example usage:
N, M, edges = tcgen()
print_test_case(N, M, edges)
```

### Explanation:
1. **generate_tree(N)**: This function generates a random tree with \( N \) vertices. A tree with \( N \) vertices has exactly \( N-1 \) edges. It ensures that the graph is connected.
2. **generate_additional_edges(N, M, tree_edges)**: This function generates additional edges to make the total number of edges equal to \( M \). It ensures that there are no self-loops or multiple edges and that the graph remains connected.
3. **tcgen()**: This function generates \( N \), \( M \), and the list of edges combining the tree edges and additional edges.
4. **print_test_case(N, M, edges)**: This function prints the generated test case in the required format.

You can run this script to generate a test case for the given problem. The generated test case will be printed to the standard output.

Extract Arguments

def extract_arguments(fh):
    N, M = map(int, fh.readline().strip().split())
    edges = []
    for _ in range(M):
        a, b = map(int, fh.readline().strip().split())
        edges.append((a, b))
    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)