给定三个整数N , D和K。任务是检查是否可以制造出具有正好N个顶点, D直径(任意两个顶点之间的最长路径中的边数)以及每个顶点的度数最多为K的树。如果可能,则打印所有可能的边缘,否则打印No。
例子:
Input: N = 6, D = 3, K = 4
Output:
1 2
2 3
3 4
5 2
6 2
Input: N = 6, D = 2, K = 4
Output: N0
方法:让我们使用以下算法构造树:如果(d> n – 1),则打印“ No”并终止程序。否则,让我们保留长度n的数组deg,它将代表顶点的度数。
第一步是构造树的直径。让第一个(d + 1)顶点形成它。
让我们在答案中添加d个边,并增加与这些边相对应的顶点的度,如果某个顶点的度大于k,则打印“否”并终止程序。
第二步(也是最后一步)是将其余(n – d – 1)个顶点附加到树上。如果其度数小于k,则称其为自由顶点。另外,让我们在某些数据结构中保留形成直径的所有自由顶点,这使我们能够以与其他任何顶点的最大距离为最小的顶点来移除这些顶点。例如,可以通过成对的集合(dist v ,v)来完成,其中dist v是从顶点v到任何其他顶点的最大距离。现在,将所有从顶点(d + 1)(0索引)到顶点n?1的顶点相加,让当前顶点为u。可以得到与任何其他顶点之间具有最小最大距离的顶点,将其设为v。现在增加顶点u和v的度数,添加它们之间的边,如果v仍然自由,则将其返回到数据结构,否则将其删除。与顶点u相同(很明显,它与其他任何顶点的最大距离将等于(dist v +1)。
如果在任何步骤我们的数据结构为空或最小最大距离等于d,则答案为“否”。否则,我们可以打印答案。
下面是上述方法的实现:
CPP
// C++ implementation of the approach
#include
using namespace std;
// Function to Make a tree with n vertices, d as it's
// diameter and degree of each vertex is at most k
void Make_tree(int n, int d, int k)
{
// If diameter > n - 1
// impossible to build tree
if (d > n - 1) {
cout << "No";
return;
}
// To store the degree of each vertex
vector deg(n);
// To store the edge between vertices
vector > ans;
// To store maximum distance among
// all the paths from a vertex
set > q;
// Make diameter of tree equals to d
for (int i = 0; i < d; ++i) {
++deg[i];
++deg[i + 1];
if (deg[i] > k || deg[i + 1] > k) {
cout << "NO" << endl;
return;
}
// Add an edge between them
ans.push_back(make_pair(i, i + 1));
}
// Store maximum distance of each vertex
// from other vertices
for (int i = 1; i < d; ++i)
q.insert(make_pair(max(i, d - i), i));
// For next (n - d - 1) edges
for (int i = d + 1; i < n; ++i) {
// If the vertex already has the degree k
while (!q.empty() && deg[q.begin()->second] == k)
q.erase(q.begin());
// If not possible
if (q.empty() || q.begin()->first == d) {
cout << "No";
return;
}
// Increase the degree of vertices
++deg[i];
++deg[q.begin()->second];
// Add an edge between them
ans.push_back(make_pair(i, q.begin()->second));
// Store the maximum distance of this vertex
// from other vertices
q.insert(make_pair(q.begin()->first + 1, i));
}
// Print all the edges of the built tree
for (int i = 0; i < n - 1; ++i)
cout << ans[i].first + 1 << " "
<< ans[i].second + 1 << endl;
}
// Driver code
int main()
{
int n = 6, d = 3, k = 4;
Make_tree(n, d, k);
return 0;
}
Python3
# Python3 implementation of the approach
# Function to Make a tree with n vertices, d as it's
# diameter and degree of each vertex is at most k
def Make_tree(n, d, k):
# If diameter > n - 1
# impossible to build tree
if (d > n - 1):
print("No")
return
# To store the degree of each vertex
deg = [0]*(n)
# To store the edge between vertices
ans = []
# To store maximum distance among
#all the paths from a vertex
q = {}
# Make diameter of tree equals to d
for i in range(d):
deg[i] += 1
deg[i + 1] += 1
if (deg[i] > k or deg[i + 1] > k):
print("NO")
return
# Add an edge between them
ans.append((i, i + 1))
# Store maximum distance of each vertex
# from other vertices
for i in range(1, d):
q[(max(i, d - i), i)] = 1
# For next (n - d - 1) edges
for i in range(d + 1, n):
arr = list(q.keys())
# If the vertex already has the degree k
while (len(q) > 0 and deg[arr[0][1]] == k):
del q[arr[0]]
# If not possible
if (len(q) == 0 or arr[0][0] == d):
print ("No")
return
# Increase the degree of vertices
deg[i] += 1
deg[arr[0][1]] += 1
# Add an edge between them
ans.append((i, arr[0][1]))
# Store the maximum distance of this vertex
# from other vertices
q[(arr[0][0] + 1, i)] = 1
# Prall the edges of the built tree
for i in range(n - 1):
print(ans[i][0] + 1, ans[i][1]+ 1)
# Driver code
if __name__ == '__main__':
n, d, k = 6, 3, 4
Make_tree(n, d, k)
# This code is contributed by mohit kumar 29.
1 2
2 3
3 4
5 2
6 2