Lights (Codeforces 1907G)
Tags: Greedy, graphs

In the end of the day, Anna needs to turn off the lights in the office. There are $$$n$$$ lights and $$$n$$$ light switches, but their operation scheme is really strange. The switch $$$i$$$ changes the state of light $$$i$$$, but it also changes the state of some other light $$$a_i$$$ (change the state means that if the light was on, it goes off and vice versa).Help Anna to turn all the lights off using minimal number of switches, or say it is impossible.

Input: The first line of input contains a single integer $$$t$$$ ($$$1 \le t \le 10^4$$$) — the number of test cases. Descriptions of test cases follow.The first line of each test case contains the integer $$$n$$$ ($$$2 \le n \le 10^5$$$) — the number of lights. The second line of each test case contains the string of $$$n$$$ characters, the initial state of the lights. Character "0" means that the corresponding light is off, and "1" means that it is on. The third line of each test case contains $$$n$$$ integers $$$a_i$$$ ($$$1 \le a_i \le n$$$, $$$a_i \neq i$$$) — the switch $$$i$$$ changes the states of light $$$i$$$ and light $$$a_i$$$.It is guaranteed that sum of $$$n$$$ over all test cases does not exceed $$$2 \cdot 10^5$$$

Output: For each test case output the integer $$$k$$$, the minimal number of switches to use, then in the separate line output the list of $$$k$$$ switches.If it is impossible to turn off all the lights, output single integer $$$-1$$$.


Sample Inputs:
8
5
11101
4 3 4 2 2
2
10
2 1
10
0000000011
9 10 10 7 10 9 9 9 10 2
10
1000111101
9 3 8 9 2 1 3 7 2 7
10
0001101010
5 7 6 10 8 3 6 6 2 2
10
0101100010
8 7 7 9 9 4 1 4 2 7
10
1010111010
7 9 10 7 7 2 8 6 10 4
10
1110000001
3 10 10 1 10 8 6 3 2 1

Sample Outputs:
3
1 5 3 
-1
1
9 
5
5 6 10 2 3 
6
4 9 5 10 8 7 
3
5 4 9 
6
1 3 5 9 7 8 
2
2 1

Solution (Python):
import sys, os, io
input = io.BytesIO(os.read(0, os.fstat(0).st_size)).readline
t = int(input())
inf = pow(10, 9) + 1
ans = []
for _ in range(t):
    n = int(input())
    s = list(input().rstrip())
    s = [0] + [i & 1 for i in s]
    a = [0] + list(map(int, input().split()))
    cnt = [0] * (n + 1)
    for i in a[1:]:
        cnt[i] += 1
    q = []
    for i in range(1, n + 1):
        if not cnt[i]:
            q.append(i)
    ans0 = []
    for i in q:
        j = a[i]
        if s[i]:
            ans0.append(i)
            s[i] ^= 1
            s[j] ^= 1
        cnt[j] -= 1
        if not cnt[j]:
            q.append(j)
    ok = 1
    for i in range(1, n + 1):
        if not cnt[i]:
            continue
        (x, u, v) = ([i], [], [])
        if s[i]:
            u.append(i)
            s[i] ^= 1
            s[a[i]] ^= 1
        else:
            v.append(i)
        while a[x[-1]] ^ i:
            x.append(a[x[-1]])
            j = x[-1]
            if s[j]:
                u.append(j)
                s[j] ^= 1
                s[a[j]] ^= 1
            else:
                v.append(j)
        if s[i] or s[j]:
            ok = 0
            break
        if len(u) > len(v):
            u = v
        for j in u:
            ans0.append(j)
        for j in x:
            cnt[j] = 0
    if ok:
        k = len(ans0)
        ans.append(str(k))
        ans.append(' '.join(map(str, ans0)))
    else:
        ans0 = -1
        ans.append(str(ans0))
sys.stdout.write('\n'.join(ans))

Solution (Python):
import sys, os, io
input = io.BytesIO(os.read(0, os.fstat(0).st_size)).readline
t = int(input())
inf = pow(10, 9) + 1
ans = []
for _ in range(t):
    n = int(input())
    s = list(input().rstrip())
    s = [0] + [i & 1 for i in s]
    a = [0] + list(map(int, input().split()))
    cnt = [0] * (n + 1)
    for i in a[1:]:
        cnt[i] += 1
    q = []
    for i in range(1, n + 1):
        if not cnt[i]:
            q.append(i)
    ans0 = []
    for i in q:
        j = a[i]
        if s[i]:
            ans0.append(i)
            s[i] ^= 1
            s[j] ^= 1
        cnt[j] -= 1
        if not cnt[j]:
            q.append(j)
    ok = 1
    for i in range(1, n + 1):
        if not cnt[i]:
            continue
        (x, u, v) = ([i], [], [])
        if s[i]:
            u.append(i)
            s[i] ^= 1
            s[a[i]] ^= 1
        else:
            v.append(i)
        while a[x[-1]] ^ i:
            x.append(a[x[-1]])
            j = x[-1]
            if s[j]:
                u.append(j)
                s[j] ^= 1
                s[a[j]] ^= 1
            else:
                v.append(j)
        if s[i] or s[j]:
            ok = 0
            break
        if len(u) > len(v):
            u = v
        for j in u:
            ans0.append(j)
        for j in x:
            cnt[j] = 0
    if ok:
        k = len(ans0)
        ans.append(str(k))
        ans.append(' '.join(map(str, ans0)))
    else:
        ans0 = -1
        ans.append(str(ans0))
sys.stdout.write('\n'.join(ans))

Solution (Python):
import sys, os, io
input = io.BytesIO(os.read(0, os.fstat(0).st_size)).readline
t = int(input())
inf = pow(10, 9) + 1
result = []
for _ in range(t):
    n = int(input())
    s = list(input().rstrip())
    s = [0] + [i & 1 for i in s]
    a = [0] + list(map(int, input().split()))
    cnt = [0] * (n + 1)
    for i in a[1:]:
        cnt[i] += 1
    q = []
    for i in range(1, n + 1):
        if not cnt[i]:
            q.append(i)
    ans0 = []
    for i in q:
        j = a[i]
        if s[i]:
            ans0.append(i)
            s[i] ^= 1
            s[j] ^= 1
        cnt[j] -= 1
        if not cnt[j]:
            q.append(j)
    ok = 1
    for i in range(1, n + 1):
        if not cnt[i]:
            continue
        (x, u, v) = ([i], [], [])
        if s[i]:
            u.append(i)
            s[i] ^= 1
            s[a[i]] ^= 1
        else:
            v.append(i)
        while a[x[-1]] ^ i:
            x.append(a[x[-1]])
            j = x[-1]
            if s[j]:
                u.append(j)
                s[j] ^= 1
                s[a[j]] ^= 1
            else:
                v.append(j)
        if s[i] or s[j]:
            ok = 0
            break
        if len(u) > len(v):
            u = v
        for j in u:
            ans0.append(j)
        for j in x:
            cnt[j] = 0
    if ok:
        k = len(ans0)
        result.append(str(k))
        result.append(' '.join(map(str, ans0)))
    else:
        ans0 = -1
        result.append(str(ans0))
sys.stdout.write('\n'.join(result))