主要坑在了多解时,假设最多的度数是 d 则 a[d+2] == a[d+1] 时,d+1 和 d+2 是可以互换的。但是互换只限于发现这对点之后加到图里的边,开始全部互换了错了很多次。
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn = 101;
struct node {
int num, deg;
bool operator<(const node &b)const {return deg > b.deg;}
}a[maxn];
int u[maxn*maxn], v[maxn*maxn];
int main()
{
int n;
while (~scanf("%d", &n)) {
memset(u, 0, sizeof(u));
memset(v, 0, sizeof(v));
for (int i = 0; i < maxn; i++)
a[i].num = a[i].deg = 0;
bool ok = true, uni = true;
int x, y, cnt = 0, sum = 0, bcnt = 0;
for (int i = 0; i < n; i++) {
a[i].num = i+1;
scanf("%d", &a[i].deg);
sum += a[i].deg;
}
if (sum & 1) {
puts("IMPOSSIBLE");
continue;
}
for (int i = 0; ok && i < n; i++) {
sort(a+i, a+n);
if (a[i].deg == 0) break;
for (int j = 1; j <= a[i].deg; j++) {
if (j == a[i].deg && i+j+1 < n && a[i+j].deg == a[i+j+1].deg) {
uni = false;
x = a[i+j].num, y = a[i+j+1].num;
bcnt = cnt;
}
if (i+j >= n || --a[i+j].deg < 0) {
ok = false;
break;
}
u[cnt] = a[i].num;
v[cnt] = a[i+j].num;
cnt++;
}
}
if (!ok)
puts("IMPOSSIBLE");
else if (uni) {
printf("UNIQUE\n%d %d\n", n, cnt);
for (int i = 0; i < cnt; i++)
printf("%d%c", u[i], i == cnt-1 ? '\n' : ' ');
for (int i = 0; i < cnt; i++)
printf("%d%c", v[i], i == cnt-1 ? '\n' : ' ');
} else {
printf("MULTIPLE\n%d %d\n", n, cnt);
for (int i = 0; i < cnt; i++)
printf("%d%c", u[i], i == cnt-1 ? '\n' : ' ');
for (int i = 0; i < cnt; i++)
printf("%d%c", v[i], i == cnt-1 ? '\n' : ' ');
printf("%d %d\n", n, cnt);
for (int i = 0; i < cnt; i++) {
if (i >= bcnt) {
if (u[i] == x) u[i] = y;
else if (u[i] == y) u[i] = x;
}
printf("%d%c", u[i], i == cnt-1 ? '\n' : ' ');
}
for (int i = 0; i < cnt; i++) {
if (i >= bcnt) {
if (v[i] == x) v[i] = y;
else if (v[i] == y) v[i] = x;
}
printf("%d%c", v[i], i == cnt-1 ? '\n' : ' ');
}
}
}
return 0;
}