Let us consider the conditions for the existence of a solution. Each part of the graph contains vertices. Since the degree of each vertex must be at least and at most , the total number of edges must satisfy the following constraints:
If this condition is not satisfied, it is impossible to construct the required graph.
Now let us move on to constructing the graph. Let's use a constructive approach: we connect vertices from the left part to vertices from the right part using cyclic shifts.
Initialize the variable cur = 0.
For each i~(1 \le i \le n), add an edge between vertex in the left part and the vertex in the right part with index j = i + cur. If j > n, we instead take j = i + cur - n, i.e., we effectively use modulo indexing. After adding each edge, we increment the edge counter. As soon as the total number of added edges becomes equal to , the algorithm terminates.
Increase cur = cur + 1 and repeat step .
Thus, at each iteration we add a "shifted" set of edges, which guarantees a uniform distribution of vertex degrees. As a result, the degree of each vertex does not exceed , and with a sufficient number of iterations, it reaches at least .
Example
The graph shown in the example has the following form:
Algorithm implementation
Read the number of test cases .
scanf("%d", &tests);
while (tests--)
{Read the input data for the current test case.
scanf("%d %d %d %d", &n, &m, &d, &D);If it is impossible to construct the graph due to violation of the required inequalities, print .
if (n * d > m || n * D < m)
{
printf("-1\n");
continue;
}Set cur = 0.
cur = 0;
while (m > 0)
{Until exactly edges are constructed, build them according to the described algorithm.
for (i = 1; i <= n; i++)
{
j = (i + cur) % n;
if (j == 0) j = n;Print the edge .
printf("%d %d\n", i, j);
m--;As soon as all edges are constructed, terminate the program.
if (m == 0) break;
}Increment the variable by .
cur++;
}
}