結果
問題 | No.2981 Pack Tree into Grid |
ユーザー |
👑 |
提出日時 | 2024-12-05 00:58:08 |
言語 | C (gcc 13.3.0) |
結果 |
AC
|
実行時間 | 6 ms / 2,000 ms |
コード長 | 4,356 bytes |
コンパイル時間 | 1,753 ms |
コンパイル使用メモリ | 33,840 KB |
実行使用メモリ | 5,248 KB |
最終ジャッジ日時 | 2024-12-05 00:58:12 |
合計ジャッジ時間 | 2,393 ms |
ジャッジサーバーID (参考情報) |
judge2 / judge5 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 1 |
other | AC * 28 |
ソースコード
#include <stdio.h>typedef struct Edge {struct Edge *next;int v, flag;} edge;int next_permutation(int n, int p[]){int i, head, tail = 0;static int q[5];for (i = n - 1, q[tail++] = p[n]; i >= 1; i--) {if (p[i] >= p[i+1]) q[tail++] = p[i];else break;}if (i == 0) return 0;int l = 0, r = tail - 1, m;while (l < r) {m = (l + r) / 2;if (q[m] <= p[i]) l = m + 1;else r = m;}p[i] ^= q[l];q[l] ^= p[i];p[i] ^= q[l];for (i++, head = 0; i <= n; i++, head++) p[i] = q[head];return 1;}int tree_isomorphism(int r, edge *adj[], int rr, edge *adjj[], int ans[]){int n = 0, nn = 0, q[5], qq[5];edge *p, *pp;for (p = adj[r]; p != NULL; p = p->next) if (p->flag != 0) q[++n] = p->v;for (pp = adjj[rr]; pp != NULL; pp = pp->next) if (pp->flag != 0) qq[++nn] = pp->v;if (n == 0 && nn == 0) {ans[r] = rr;return 1;} else if (n != nn) return 0;int i, perm[5];for (i = 1; i <= n; i++) perm[i] = i;for (i = 1; i <= n; i++) {for (p = adj[q[i]]; p != NULL; p = p->next) if (p->v == r) p->flag = 0;for (pp = adjj[qq[i]]; pp != NULL; pp = pp->next) if (pp->v == rr) pp->flag = 0;}do {for (i = 1; i <= n; i++) if (tree_isomorphism(q[i], adj, qq[perm[i]], adjj, ans) == 0) break;if (i > n) {for (i = 1; i <= n; i++) {for (p = adj[q[i]]; p != NULL; p = p->next) if (p->v == r) p->flag = 1;for (pp = adjj[qq[i]]; pp != NULL; pp = pp->next) if (pp->v == rr) pp->flag = 1;}ans[r] = rr;return 1;}} while (next_permutation(n, perm));for (i = 1; i <= n; i++) {for (p = adj[q[i]]; p != NULL; p = p->next) if (p->v == r) p->flag = 1;for (pp = adjj[qq[i]]; pp != NULL; pp = pp->next) if (pp->v == rr) pp->flag = 1;}return 0;}int solve(int N, int a[], int b[], int c[], int H, int W, char S[][27], int ans[][2]){int i, j, u, w, n = 0, m = 0, v[14][27], v_inv[301][2];static edge *adj[2][301], e[2][601];for (i = 1; i <= H; i++) {for (j = 1; j <= W; j++) {if (S[i][j] == '#') {v[i][j] = ++n;v_inv[n][0] = i;v_inv[n][1] = j;} else v[i][j] = 0;}}for (i = 1; i <= n; i++) {adj[0][i] = NULL;adj[1][i] = NULL;}for (i = 1; i <= H; i++) {for (j = 1; j <= W; j++) {if (S[i][j] != '#') continue;if (S[i+1][j] == '#') {u = v[i][j];w = v[i+1][j];e[0][m].v = w;e[0][m].flag = 1;e[0][m].next = adj[0][u];adj[0][u] = &(e[0][m++]);e[0][m].v = u;e[0][m].flag = 1;e[0][m].next = adj[0][w];adj[0][w] = &(e[0][m++]);}if (S[i][j+1] == '#') {u = v[i][j];w = v[i][j+1];e[0][m].v = w;e[0][m].flag = 1;e[0][m].next = adj[0][u];adj[0][u] = &(e[0][m++]);e[0][m].v = u;e[0][m].flag = 1;e[0][m].next = adj[0][w];adj[0][w] = &(e[0][m++]);}}}int sum = 0;static int deg[301];for (i = 1; i <= N - 1; i++) sum += c[i];if (sum != n - 1) return 0;for (i = 1; i <= n; i++) deg[i] = 0;for (i = 1, n = N, m = 0; i <= N - 1; i++) {u = a[i];while (c[i] > 1) {c[i]--;w = ++n;e[1][m].v = w;e[1][m].flag = 1;e[1][m].next = adj[1][u];adj[1][u] = &(e[1][m++]);e[1][m].v = u;e[1][m].flag = 1;e[1][m].next = adj[1][w];adj[1][w] = &(e[1][m++]);deg[u]++;deg[w]++;u = w;}w = b[i];e[1][m].v = w;e[1][m].flag = 1;e[1][m].next = adj[1][u];adj[1][u] = &(e[1][m++]);e[1][m].v = u;e[1][m].flag = 1;e[1][m].next = adj[1][w];adj[1][w] = &(e[1][m++]);deg[u]++;deg[w]++;}for (i = 1; i <= n; i++) if (deg[i] > 4) return 0;int perm[301];for (i = 1; i <= n; i++) if (tree_isomorphism(1, adj[1], i, adj[0], perm) != 0) break;if (i > n) return 0;for (i = 1; i <= N; i++) {ans[i][0] = v_inv[perm[i]][0];ans[i][1] = v_inv[perm[i]][1];}return 1;}int main(){int T, N, u[301], v[301], w[301], i, j, H, W, ans[301][2];char S[14][27];scanf("%d", &T);while (T--) {scanf("%d", &N);for (i = 1; i <= N - 1; i++) scanf("%d %d %d", &(u[i]), &(v[i]), &(w[i]));scanf("%d %d", &H, &W);for (i = 0; i <= H + 1; i++) for (j = 0; j <= W + 1; j++) S[i][j] = 0;for (i = 1; i <= H; i++) scanf("%s", &(S[i][1]));if (solve(N, u, v, w, H, W, S, ans) != 0) {printf("Yes\n");for (i = 1; i <= N; i++) printf("%d %d\n", ans[i][0], ans[i][1]);} else printf("No\n");}fflush(stdout);return 0;}