第一行输入一个正整数
,代表二分图的节点数量。
第二行输入
个正整数
,代表每个节点的度数。
如果答案不存在,直接输出
。
否则,请参考下方的格式输出。
第一行输出一个整数
代表边的数量。
接下来的
行,每行输出两个正整数
代表节点
和节点
有一条边连接。
构造的图可以包含重边,但不能包含自环。构造的最终的图可以不连通,你只需要保证每个连通分量均为二分图。
如果存在多个解决方案,您可以输出任意一个,系统会自动判定是否正确。注意,自测运行功能可能因此返回错误结果,请自行检查答案正确性。
3 1 2 1
2 1 2 2 3
构造的图是一棵树,显然所有树都是二分图。
3 2 2 2
-1
只能构造一个三元环,显然不是二分图。
只能想到暴力解法了 。。。。 n = int(input()) d = list(map(int, input().split())) nodes = [] for idx, node in enumerate(d): nodes.append((idx, node)) # (node名称, 度数) total_sides = sum(d) if total_sides % 2 != 0: print(-1) exit(0) target_sides = int(total_sides // 2) # 二分图的性质 # 1. 左右两边度相等 # 2. 左边度的最大值不能超过右边节点数量,右边同理。因为允许重边,所以不需要进一步考虑节点和边的对应关系 sorted_nodes = sorted(nodes, key=lambda x: x[1], reverse=True) # 先想办法让左右两边度相等 curr_side = 0 def dfs(curr_side, target_side, begin, n): if curr_side == target_side: return [] if begin == n-1: return None for i in range(begin+1, n): curr_node = sorted_nodes[i] choices = dfs(curr_side+curr_node[1], target_side, i, n) # 选择当前node if choices is not None: choices.append(list(curr_node)) return choices choices = dfs(curr_side, target_side, i, n) # 不选择当前node if choices is not None: return choices return None left_list = dfs(0, target_sides, -1, n) if left_list is None: print(-1) exit(0) max_sides = left_list[0][1] if max_sides + len(left_list) > n: print(-1) exit(0) left_list = sorted(left_list, key=lambda x: x[0]) # 按序号排序 right_list = [] last_idx = 0 for each in left_list: for i in range(last_idx, each[0]): right_list.append(list(nodes[i])) last_idx = each[0] + 1 for i in range(last_idx, n): right_list.append(list(nodes[i])) # 打印边数量 print(target_sides) # 从left_list一个一个取值 然后对应到right_list curr_right_idx = 0 for each in left_list: while each[1] > 0: tmp_r = right_list[curr_right_idx] if tmp_r[1] == 0: curr_right_idx += 1 continue tmp_min = min(tmp_r[1], each[1]) tmp_r[1] -= tmp_min each[1] -= tmp_min for _ in range(tmp_min): print(each[0]+1, tmp_r[0]+1) # 序号要+1