The 2020 ICPC Asia Macau Regional Contest F. Fixing Networks(构造)
After the last network breakdown, you've been assigned to redesign the signal transmission network of ICPC (Internet Clogging Prevention Corporation)!
There are 𝑛n signal stations in total, they are all newly built and can establish bidirectional signal connections with at most 𝑑d other stations. ICPC demands you to reach the full potential of the network with these fancy stations. That is, all stations should have exactly 𝑑d connections, no connection with oneself, and no multiple connections between the same pair of stations.
These stations will later be assigned to 𝑐c departments of ICPC. Each department wants at least one station, and all stations will be assigned to these departments. To prevent another network breakdown, all stations assigned to the same department should be able to communicate with each other, while stations assigned to different departments should not be able to do so. Two stations can communicate with each other when there is a sequence of stations that begins and ends at these two stations, and every adjacent station in the sequence has a direct signal connection.
Assigning stations to departments is not your job; However, since you are probably the only responsible person left in ICPC, you want to make sure it is at least possible. Give a network proposal that satisfies all the restrictions above, or determine it is impossible.
Input
The only line of the input contains three integers 𝑛,𝑑n,d and 𝑐c (1≤𝑐≤𝑛≤1000001≤c≤n≤100000, 0≤𝑑<𝑛0≤d<n, 𝑛×𝑑≤200000n×d≤200000), denoting the number of signal stations, the number of connections each station can establish, and the number of departments.
Output
If it is impossible to connect the stations in such a way, print a single line containing "No". Otherwise, print "Yes" in the first line, then print 𝑛n lines, with the 𝑖i-th line containing 𝑑d numbers, denoting the 𝑑dstations that have connections with the 𝑖i-th station. The 𝑑d numbers should be sorted in ascending order.
The label of all stations should be integers in the range [1,𝑛][1,n]. If there is more than one solution, any one of them will be accepted.
Examples
input
Copy
12 3 2
output
Copy
Yes
2 5 8
1 3 6
2 4 7
3 5 8
1 4 6
2 5 7
3 6 8
1 4 7
10 11 12
9 11 12
9 10 12
9 10 11
input
Copy
3 2 2
output
Copy
No
首先看到数据范围,需要特判d = 1和d = 0。然后需要判断输出No的情况 ,即c * (d + 1) > n || (n & 1) && (d & 1),因为最小的满足要求的联通块大小为d + 1,同时边数为n * d / 2,如果n和d均为奇数则边数不是整数。
然后就是构造了,首先对于c - 1个块每个块直接用d + 1个点即可,剩下的点则凑最后一个块。因为每个点度数一样,根据对称性考虑造一个环,每个点连接前\(\lfloor\frac{d}{2}\rfloor\)个点和后\(\lfloor\frac{d}{2}\rfloor\)个点,如果d为奇数的话则连接对面的那个点(因为n为偶数,一定能保证有这样一个点)。
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int n, c, d;
int main() {
cin >> n >> d >> c;
if(d == 0) {
if(n == c) {
puts("Yes");
} else puts("No");
return 0;
} else if(d == 1) {
if(c * 2 == n) {
puts("Yes");
for(int i = 1; i <= n; i += 2) {
cout << i + 1 << endl;
cout << i << endl;
}
} else {
puts("No");
}
return 0;
}
if(c * (d + 1) > n || (n & 1) && (d & 1)) {
puts("No");
return 0;
}
puts("Yes");
int num = n / (d + 1);
int res = n - (c - 1) * (d + 1);
for(int i = 1; i <= res; i++) {
int k = d / 2;
vector<int> ans;
for(int j = i - k; j <= i + k; j++) {
if(i == j) continue;
if(j <= 0) ans.push_back(j + res);
else if(j > res) ans.push_back(j % res);
else ans.push_back(j);
}
if(d & 1) ans.push_back((i + res / 2) % res + ((i + res / 2) % res == 0 ? res : 0));
sort(ans.begin(), ans.end());
for(auto x : ans) cout << x << " ";
cout << endl;
}
for(int i = res + 1; i <= n; i += (d + 1)) {
//i...i+d
for(int j = i; j <= i + d; j++) {
for(int k = i; k <= i + d; k++) {
if(j == k) continue;
cout << k << " ";
}
cout << endl;
}
}
return 0;
}