水题:考虑把a[i]从大到小排序,然后每个节点都从后往前连边,那么就保证了不会出现重复情况(即连了一个几点却没有与这个节点的儿子直接连边),所以每个节点就要从后往前连a[i]条边,如果没法连就是不合法的情况。
#include <stdio.h>
#include <stdlib.h>
#include <algorithm>
using namespace std;
const int maxn = 10000;
struct Node {
int val, index;
bool operator<(const Node &other) const {
return val > other.val;
}
}a[maxn];
int n, sum;
int main() {
int tt;
scanf("%d", &tt);
for (int cases = 1; cases <= tt; cases++) {
bool flag = true;
scanf("%d", &n);
for (int i = 1; i <= n; i++) {
scanf("%d", &a[i].val);
a[i].index = i;
}
sort(a+1, a+1+n);
sum = 0;
for (int i = n; i >= 1; i--) {
if (n-i < a[i].val) flag = false;
sum += a[i].val;
}
printf("Case #%d: ", cases);
if (flag) printf("Yes\n");
else {
printf("No\n"); continue;
}
printf("%d\n", sum);
for (int i = n; i >= 1; i--)
for (int j = n; j >= n-a[i].val+1; j--) {
printf("%d %d\n", a[i].index, a[j].index);
}
}
}