Description
有一棵n个点的无根树,每条边有一个正整数权值,表示长度,定义两点距离为在树上的最短路径的长度。
已知2到n-1每个点在树上与1和n的距离,请根据这些信息还原出这棵树。
Sample Input
7
6 6 2 2 1
5 3 5 1 4
Sample Output
TAK
1 5 2
5 7 1
5 2 4
7 3 3
1 4 2
1 6 1
你选一个最短的x+y的值,然后把这条链选出来,不断在这条链上插点。
特殊情况有点多,可以看我的代码。。。
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long LL;
int _min(int x, int y) {return x < y ? x : y;}
int _max(int x, int y) {return x > y ? x : y;}
int read() {
int s = 0, f = 1; char ch = getchar();
while(ch < '0' || ch > '9') {if(ch == '-') f = -1; ch = getchar();}
while(ch >= '0' && ch <= '9') s = s * 10 + ch - '0', ch = getchar();
return s * f;
}
void put(int x) {
if(x == 0) {putchar('0'); putchar(' '); return ;}
char num[10]; int len = 0;
while(x) num[++len] = x % 10 + '0', x /= 10;
for(int i = len; i; i--) putchar(num[i]);
putchar(' ');
}
struct node {
int x, y, id, pos;
} a[510000];
struct edge {
int x, y, c;
} e[510000]; int o;
int tp, sta[510000], gg[510000];
bool cmp(node a, node b) {return a.x < b.x;}
bool cmp1(node a, node b) {return a.x - a.pos < b.x - b.pos;}
int main() {
int n = read();
if(n == 2) {
puts("TAK");
puts("1 2 3");
return 0;
}
for(int i = 2; i < n; i++) a[i].x = read();
for(int i = 2; i < n; i++) a[i].y = read(), a[i].id = i;
if(a[2].x != a[2].y) {
int val = abs(a[2].x - a[2].y), i = 3;
for(i = 3; i < n; i++) {
if(abs(a[i].x - a[i].y) != val) break;
} if(i == n) {
puts("TAK");
printf("1 %d %d\n", n, val);
for(int i = 2; i < n; i++) {
if(a[i].x < a[i].y) printf("1 %d %d\n", i, a[i].x);
else printf("%d %d %d\n", i, n, a[i].y);
} return 0;
}
}
sort(a + 2, a + n, cmp);
int minn = 0x3f3f3f3f;
for(int i = 2; i < n; i++) minn = _min(minn, a[i].x + a[i].y);
sta[tp = 1] = 1; a[n].x = minn; gg[1] = 0;
for(int i = 2; i < n; i++) if(a[i].x + a[i].y == minn) sta[++tp] = a[i].id, gg[tp] = a[i].x;
sta[++tp] = n; gg[tp] = minn;
for(int i = 2; i <= tp; i++) {
if(gg[i] == gg[i - 1]) {puts("NIE"); return 0;}
e[++o].x = sta[i - 1], e[o].y = sta[i], e[o].c = gg[i] - gg[i - 1];
}
for(int i = 2; i < n; i++) {
if(a[i].x + a[i].y != minn) {
a[i].pos = (a[i].x + a[i].y - minn);
if(a[i].pos % 2) {puts("NIE"); return 0;}
a[i].pos /= 2;
}
} sort(a + 2, a + n, cmp1);
int gt = 0;
for(int i = 2; i < n; i++) {
if(a[i].x + a[i].y != minn) {
while(gt < tp && a[i].x - a[i].pos >= gg[gt + 1]) gt++;
if(a[i].x - a[i].pos != gg[gt]) {puts("NIE"); return 0;}
e[++o].x = sta[gt], e[o].y = a[i].id; e[o].c = a[i].pos;
}
} if(o != n - 1) {puts("NIE"); return 0;}
puts("TAK");
for(int i = 1; i <= o; i++) put(e[i].x), put(e[i].y), put(e[i].c), puts("");
return 0;
}