← Home
Here is the Go solution for the "Village (Minimum)" task.

```go
package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
)

// Global variables to store graph and results
var (
	adj       [][]int
	res       []int
	swapped   []bool
	totalDist int64
	scanner   *bufio.Scanner
)

// Helper to read integers efficiently
func scanInt() int {
	scanner.Scan()
	val, _ := strconv.Atoi(scanner.Text())
	return val
}

// DFS traversal to perform the greedy matching
func dfs(u, p int) {
	for _, v := range adj[u] {
		if v == p {
			continue
		}
		dfs(v, u)
		// If the child v is not satisfied (not part of any swap/cycle),
		// we must swap/merge it with the current node u.
		if !swapped[v] {
			// Swap the destinations of the villagers currently at u and v.
			// This effectively merges v into the cycle u belongs to,
			// or creates a new swap pair (u, v).
			res[u], res[v] = res[v], res[u]
			swapped[v] = true
			swapped[u] = true
			totalDist += 2
		}
	}
}

func main() {
	// Setup fast I/O
	scanner = bufio.NewScanner(os.Stdin)
	scanner.Split(bufio.ScanWords)
	writer := bufio.NewWriter(os.Stdout)
	defer writer.Flush()

	// Increase buffer size to handle large inputs
	buf := make([]byte, 2048)
	scanner.Buffer(buf, 2*1024*1024)

	if !scanner.Scan() {
		return
	}
	N, _ := strconv.Atoi(scanner.Text())

	adj = make([][]int, N+1)
	res = make([]int, N+1)
	swapped = make([]bool, N+1)

	// Initially, every villager is in their own house (invalid state)
	for i := 1; i <= N; i++ {
		res[i] = i
	}

	// Read tree edges
	for i := 0; i < N-1; i++ {
		u := scanInt()
		v := scanInt()
		adj[u] = append(adj[u], v)
		adj[v] = append(adj[v], u)
	}

	// Perform greedy matching starting from root (1)
	dfs(1, 0)

	// If the root is still not swapped (can happen if N is odd or specific structures),
	// force a swap with any neighbor (e.g., the first child).
	// This extends the neighbor's cycle to include the root.
	if !swapped[1] {
		v := adj[1][0]
		res[1], res[v] = res[v], res[1]
		swapped[1] = true
		totalDist += 2
	}

	// Output results
	fmt.Fprintln(writer, totalDist)
	for i := 1; i <= N; i++ {
		if i > 1 {
			fmt.Fprint(writer, " ")
		}
		fmt.Fprint(writer, res[i])
	}
	fmt.Fprintln(writer)
}
```