← Home
```go
package main

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

func main() {
	// Fast I/O
	in := bufio.NewReader(os.Stdin)
	out := bufio.NewWriter(os.Stdout)
	defer out.Flush()

	var t int
	// Reading number of test cases
	if _, err := fmt.Fscan(in, &t); err != nil {
		return
	}

	for i := 0; i < t; i++ {
		solve(in, out)
	}
}

func solve(in *bufio.Reader, out *bufio.Writer) {
	var n int
	var x, y int64
	fmt.Fscan(in, &n, &x, &y)

	var a, b string
	fmt.Fscan(in, &a, &b)

	// Identify indices where strings differ
	var d []int
	for i := 0; i < n; i++ {
		if a[i] != b[i] {
			d = append(d, i)
		}
	}

	k := len(d)
	
	// If number of differences is odd, it's impossible to make strings equal
	if k%2 != 0 {
		fmt.Fprintln(out, -1)
		return
	}
	
	// If strings are already equal
	if k == 0 {
		fmt.Fprintln(out, 0)
		return
	}

	// Case 1: Cost of adjacent swap (x) is greater than or equal to non-adjacent swap (y).
	// We generally prefer using y. 
	// The only case we might use x is if we have exactly 2 adjacent defects and using 2 y operations is more expensive.
	if x >= y {
		if k == 2 {
			if d[0]+1 == d[1] {
				// Two adjacent defects.
				// Option 1: Direct adjacent swap, cost x.
				// Option 2: Swap each with a dummy helper, cost 2*y.
				ans := 2 * y
				if x < ans {
					ans = x
				}
				fmt.Fprintln(out, ans)
			} else {
				// Two non-adjacent defects, simply swap them.
				fmt.Fprintln(out, y)
			}
		} else {
			// More than 2 defects. We can always pair them up such that we pay y for each pair.
			// Even if they are adjacent, we can pair (i, k) and (i+1, j) to avoid paying x.
			fmt.Fprintln(out, int64(k/2)*y)
		}
	} else {
		// Case 2: x < y. Adjacent swaps are cheaper.
		// We use Dynamic Programming.
		// We process defects from left to right.
		// dp[0]: Cost with 0 open chains.
		// dp[1]: Cost with 1 open chain (accumulating x cost).
		// dp[2]: Cost with 1 open defect handled by y cost (already paid y/2 or waiting to close for 0). 
		//        Let's model it as: transition 0->2 pays y, closing 2->0 pays 0.
		// dp[3]: Cost with 1 open y and 1 open x (nested).

		const INF = 2e18 // Sufficiently large infinity
		dp := [4]int64{0, INF, INF, INF}

		for i := 0; i < k; i++ {
			gap := int64(0)
			if i > 0 {
				gap = int64(d[i] - d[i-1])
			}

			// Add accumulation cost for states with an open x-chain
			if dp[1] != INF {
				dp[1] += gap * x
			}
			if dp[3] != INF {
				dp[3] += gap * x
			}

			next_dp := [4]int64{INF, INF, INF, INF}

			// Transition logic at current defect d[i]
			
			// From State 0 (0 open):
			// We MUST open a new defect.
			if dp[0] != INF {
				// Open as x-chain -> State 1
				if dp[0] < next_dp[1] {
					next_dp[1] = dp[0]
				}
				// Open as y-pair -> State 2 (pay y now)
				if dp[0]+y < next_dp[2] {
					next_dp[2] = dp[0] + y
				}
			}

			// From State 1 (1 open x):
			// We can close the x-chain -> State 0
			if dp[1] != INF {
				if dp[1] < next_dp[0] {
					next_dp[0] = dp[1]
				}
				// Note: cannot keep x open and open another (would be x, x or x, y -> suboptimal or invalid)
			}

			// From State 2 (1 open y):
			// We can close the y-pair -> State 0
			if dp[2] != INF {
				if dp[2] < next_dp[0] {
					next_dp[0] = dp[2]
				}
				// Or we can nest an x-chain inside -> State 3
				if dp[2] < next_dp[3] {
					next_dp[3] = dp[2]
				}
			}

			// From State 3 (1 open y, 1 open x):
			// We must close the inner x-chain -> State 2
			if dp[3] != INF {
				if dp[3] < next_dp[2] {
					next_dp[2] = dp[3]
				}
			}

			dp = next_dp
		}
		fmt.Fprintln(out, dp[0])
	}
}
```