Problem:


Score : 600 points

Problem Statement

We have a tree with N vertices numbered 1 to N.
The i-th edge in this tree connects Vertex a_i and Vertex b_i.

Consider painting each of these edges white or black. There are 2^{N-1} such ways to paint the edges. Among them, how many satisfy all of the following M restrictions?  

The i-th (1 \leq i \leq M) restriction is represented by two integers u_i and v_i, which mean that the path connecting Vertex u_i and Vertex v_i must contain at least one edge painted black.

Constraints

2 \leq N \leq 50

1 \leq a_i,b_i \leq N

The graph given in input is a tree.

1 \leq M \leq \min(20,\frac{N(N-1)}{2})

1 \leq u_i < v_i \leq N

If i \not= j, either u_i \not=u_j or v_i\not=v_j

All values in input are integers.

Input

Input is given from Standard Input in the following format:

N
a_1 b_1
:
a_{N-1} b_{N-1}
M
u_1 v_1
:
u_M v_M

Output

Print the number of ways to paint the edges that satisfy all of the M conditions.

Sample Input 1

3
1 2
2 3
1
1 3

Sample Output 1

3

The tree in this input is shown below:

All of the M restrictions will be satisfied if Edge 1 and 2 are respectively painted (white, black), (black, white), or (black, black), so the answer is 3.

Sample Input 2

2
1 2
1
1 2

Sample Output 2

1

The tree in this input is shown below:

All of the M restrictions will be satisfied only if Edge 1 is painted black, so the answer is 1.

Sample Input 3

5
1 2
3 2
3 4
5 3
3
1 3
2 4
2 5

Sample Output 3

9

The tree in this input is shown below:

Sample Input 4

8
1 2
2 3
4 3
2 5
6 3
6 7
8 6
5
2 7
3 5
1 6
2 8
7 8

Sample Output 4

62

The tree in this input is shown below:



Sample input:
3
1 2
2 3
1
1 3


Sample output:
3

Submission status: Time Limit Exceeded

Solution code:
n=int(input())
g=[[]for i in range(n)]
for i in range(n-1):
    a,b=map(int,input().split())
    g[a-1].append((b-1,i))
    g[b-1].append((a-1,i))

def path(i,goal,mam=-1):
    if len(g[i][0])==1 and g[0]==mam:
        return 0
    else:
        for j,idx in g[i]:
            if j==mam:
                continue
            if j==goal:
                return 1<<idx
            p=path(j,goal,i)
            if p>0:
                return p | (1<<idx)
        return 0

m=int(input())
ps=[]
for _ in range(m):
    a,b=map(int,input().split())
    ps.append(path(a-1,b-1))

dp=[0]*(1<<m)
dp[0]=1
for i in range(n-1):
    newdp=[0]*(1<<m)
    hit=0
    for j,p in enumerate(ps):
        a=p & (1<<i)
        if p & (1<<i):
            hit+=1<<j
    for j in range(1<<m):
        newdp[j|hit]+=dp[j]
    for j in range(1<<m):
        dp[j]+=newdp[j]
print(dp[-1])

Submission status: Time Limit Exceeded

Solution code:
N=int(input())
edge={i:[] for i in range(1,N+1)}
for i in range(0,N-1):
    a,b=map(int,input().split())
    edge[a].append((b,i))
    edge[b].append((a,i))

parent={i:-1 for i in range(1,N+1)}
depth={i:-1 for i in range(1,N+1)}
parent[1]=(0,-1)
depth[1]=0
q=set([1])
sub=set([])
while q:
    while q:
        x=q.pop()
        for b,i in edge[x]:
            if parent[b]==-1:
                parent[b]=(x,i)
                depth[b]=depth[x]+1
                sub.add(b)

        if not q:
            q=sub
            sub=set([])
            break

M=int(input())
condition=[[] for i in range(0,M)]
for i in range(0,M):
    u,v=map(int,input().split())
    ans=set([])
    while depth[u]!=depth[v]:
        if depth[u]>depth[v]:
            U,j=parent[u]
            ans.add(j)
            u=U
        else:
            V,j=parent[v]
            ans.add(j)
            v=V

    while u!=v:
        U,j=parent[u]
        ans.add(j)
        u=U
        V,j=parent[v]
        ans.add(j)
        v=V
    condition[i]=ans

ans=2**(N-1)
ban=0
for i in range(1,2**M):
    num=bin(i).count('1')
    s=set([])
    for j in range(0,M):
        if i>>j &1==1:
            for k in condition[j]:
                s.add(k)

    n=len(s)
    if num%2==1:
        ban+=2**(N-1-n)
    else:
        ban-=2**(N-1-n)

print(ans-ban)

Submission status: Time Limit Exceeded

Solution code:
N=int(input())
edge={i:[] for i in range(1,N+1)}
for i in range(0,N-1):
    a,b=map(int,input().split())
    edge[a].append((b,i))
    edge[b].append((a,i))

parent={i:-1 for i in range(1,N+1)}
depth={i:-1 for i in range(1,N+1)}
parent[1]=(0,-1)
depth[1]=0
q=set([1])
sub=set([])
while q:
    while q:
        x=q.pop()
        for b,i in edge[x]:
            if parent[b]==-1:
                parent[b]=(x,i)
                depth[b]=depth[x]+1
                sub.add(b)

        if not q:
            q=sub
            sub=set([])
            break

M=int(input())
condition=[[] for i in range(0,M)]
for i in range(0,M):
    u,v=map(int,input().split())
    ans=set([])
    while depth[u]!=depth[v]:
        if depth[u]>depth[v]:
            U,j=parent[u]
            ans.add(j)
            u=U
        else:
            V,j=parent[v]
            ans.add(j)
            v=V

    while u!=v:
        U,j=parent[u]
        ans.add(j)
        u=U
        V,j=parent[v]
        ans.add(j)
        v=V
    condition[i]=ans

ans=2**(N-1)
ban=0
for i in range(1,2**M):
    num=bin(i).count('1')
    s=set([])
    for j in range(0,M):
        if i>>j &1==1:
            s=s|condition[j]

    n=len(s)
    if num%2==1:
        ban+=2**(N-1-n)
    else:
        ban-=2**(N-1-n)

print(ans-ban)

Submission status: Time Limit Exceeded

Solution code:
n = int(input())
ab = [list(map(int,input().split())) for _ in range(n-1)]
m = int(input())
uv = [list(map(int,input().split())) for _ in range(m)]

from collections import deque

links = [[] for _ in range(n+1)]
for ind,val in enumerate(ab):
    a,b = val
    links[a].append((ind,b))
    links[b].append((ind,a))

def bfs(start,end):
    parent = [[-1,-1] for _ in range(n+1)]
    d = deque()
    d.append(start)
    done = set()
    while(d):
        tmp = d.popleft()
        done.add(tmp)
        for i in links[tmp]:
            link_ind, j = i
            if(not j in done):
                parent[j] = [tmp,link_ind]
                d.append(j)
    route = []
    while(True):
        route.append(parent[end][1])
        end = parent[end][0]
        if(end == start):
            break
    return route[::-1]

links_key = [0] * (n-1)
for i,se in enumerate(uv):
    start,end = se
    route = bfs(start,end)
    for j in route:
        links_key[j] =(links_key[j] | 1<<i)

dp = [[0] * (2**m) for _ in range(n)]
dp[0][0] = 1

for i in range(n-1):
     for j in range(2**m):
         dp[i+1][j] += dp[i][j]
         dp[i+1][(j|links_key[i])] += dp[i][j]

print(dp[-1][-1])

Submission status: Time Limit Exceeded

Solution code:
def examA():
    N = I()
    L = LI()
    L.sort()
    if sum(L)<=L[-1]*2:
        print("No")
    else:
        print("Yes")
    return

def examB():
    N, M = LI()
    A = [LI()for _ in range(N)]
    A.sort(key=lambda x:x[0])
    ans = 0
    for a,b in A:
        if M<=b:
            ans += a*M
            break
        ans += a*b
        M -= b
    print(ans)
    return

def examC():
    N = I()
    S = [SI()for _ in range(N)]
    D = defaultdict(int)
    for s in S:
        cur = []
        for i,j in Counter(s).items():
            cur.append((i,j))
        #print(cur)
        cur.sort()
        cur = tuple(cur)
        D[cur] += 1
    ans = 0
    for d in D.values():
        ans += (d-1)*d//2
    print(ans)
    return

def examD():
    N, K = LI()
    A = LI()
    S = [0]*(N+1)
    for i in range(N):
        S[i+1] = S[i]+A[i]
    ans = 0
    for i in range(N):
        l = i-1; r = N
        if S[-1]-S[i]<K:
            break
        while(r-l>1):
            now = (l+r)//2
            if S[now]-S[i]<K:
                l = now
            else:
                r = now
        #print(i,r)
        ans += (N-r+1)
    print(ans)
    return

def examE():
    # 区間加算、上書き、一点取得
    class SegmentTree:
        def __init__(self, n, ele, segfun):
            #####単位元######要設定0or1orinf
            self.ide_ele = ele
            self.segfun = segfun
            ####################
            self.n = n
            self.N0 = 1 << n.bit_length()
            self.data = [self.ide_ele] * (self.N0 * 2)

        def update_add(self, l, r, val):
            l += self.N0
            r += self.N0
            while l < r:
                if l & 1:
                    self.data[l] += val
                    l += 1
                if r & 1:
                    self.data[r - 1] += val
                    r -= 1
                l //= 2
                r //= 2

        def update(self, l, r, val):
            l += self.N0
            r += self.N0
            while l < r:
                if l & 1:
                    self.data[l] = self.segfun(self.data[l], val)
                    l += 1
                if r & 1:
                    self.data[r - 1] = self.segfun(self.data[r - 1], val)
                    r -= 1
                l //= 2
                r //= 2

        def query(self, i):
            i += len(self.data) // 2
            ret = self.data[i]
            while i > 0:
                i //= 2
                ret = self.segfun(ret, self.data[i])
            return ret

    N, D, A = LI()
    X = [LI()for _ in range(N)]
    X.sort()
    L = [0]*N
    for i in range(N):
        L[i] = X[i][0]
    S = SegmentTree(N,0,lambda a, b: a+b)
    ans = 0
    for i,[x,h] in enumerate(X):
        H = h - S.query(i)
        if H<=0:
            continue
        ne = bisect.bisect_right(L,x+2*D)
        #print(ne)
        need = (H-1)//A + 1
        S.update(i,ne,need*A)
        ans += need
    print(ans)
    return

def examF():
    N = I()
    V = [[]for _ in range(N)]
    Num_edge = {}
    for i in range(N-1):
        a, b = LI()
        a -= 1; b -= 1
        V[a].append(b)
        V[b].append(a)
        Num_edge[(a,b)] = i
        Num_edge[(b,a)] = i
    def dfs(S,s,p,g):
        now = s
        neS = []
        if now==g:
            return S
        for ne in V[now]:
            if ne==p:
                continue
            neS = dfs(S+[Num_edge[(now,ne)]],ne,now,g)
            if neS:
                return neS
        return
    M = I()
    Q = [set()for _ in range(M)]

    for i in range(M):
        a, b = LI()
        a -= 1; b -= 1
        q = dfs([],a,-1,b)
        for j in q:
            Q[i].add(j)
    #print(Q)
    ans = pow(2,N-1)
    loop = 2**M
    for i in range(1,loop):
        cur = set()
        num = 0
        for k in range(M):
            if i&(1<<k)>0:
                num += 1
                for visit in Q[k]:
                    cur.add(visit)
        #print(i,cur)
        if num%2==1:
            ans -= pow(2, N-len(cur)-1)
        else:
            ans += pow(2, N - len(cur)-1)
    print(ans)
    return

import sys,bisect,itertools,heapq,math,random
from copy import deepcopy
from heapq import heappop,heappush,heapify
from collections import Counter,defaultdict,deque
read = sys.stdin.buffer.read
readline = sys.stdin.buffer.readline
readlines = sys.stdin.buffer.readlines
def I(): return int(readline())
def LI(): return list(map(int,readline().split()))
def LSI(): return list(map(str,sys.stdin.readline().split()))
def LS(): return sys.stdin.readline().split()
def SI(): return sys.stdin.readline().strip()
global mod,mod2,inf,alphabet,_ep
mod = 10**9 + 7
mod2 = 998244353
inf = 10**18
_ep = 10**(-12)
alphabet = [chr(ord('a') + i) for i in range(26)]

sys.setrecursionlimit(10**7)

if __name__ == '__main__':
    examF()

"""
142
12 9 1445 0 1
asd dfg hj o o
aidn
"""

Submission status: Time Limit Exceeded

Solution code:
# 解説AC
from collections import deque

N = int(input())
edge = [[] for _ in range(N)]
for n in range(N - 1):
    a,b = map(int, input().split())
    edge[a-1].append((b-1, n))
    edge[b-1].append((a-1, n))

def bfs(s:int, g:int):
    """ 始点sから終点gまでのパスを求める """
    path = [0] * N
    visited = [False] * N
    
    que = deque([s])
    visited[s] = True
    while que:
        v = que.popleft()
        for w, n in edge[v]:
            if visited[w]: continue
            path[w] = path[v] | (1 << n)
            if w == g: return path[g]
            que.append(w)
    return path[g]

def popcount(x:int):
    """ return bin(x).count('1') """
    x = x - ((x >> 1) & 0x5555555555555555)
    x = (x & 0x3333333333333333) + ((x >> 2) & 0x3333333333333333)
    x = (x + (x >> 4)) & 0x0f0f0f0f0f0f0f0f
    x = x + (x >> 8)
    x = x + (x >> 16)
    x = x + (x >> 32)
    return x & 0x0000007f

M = int(input())
path = [0] * M # 各制約で使用するパス
for i in range(M):
    u,v = map(int, input().split())
    path[i] = bfs(u - 1, v - 1)

ans = 0
# 包除原理
for bit in range(1 << M):
    val = 0
    for i in range(M):
        if (bit >> i) & 1:
            val |= path[i]
    if popcount(bit) % 2 == 0:
        ans += 1 << (N - 1 - popcount(val))
    else:
        ans -= 1 << (N - 1 - popcount(val))

print(ans)

Submission status: Time Limit Exceeded

Solution code:
# 解説AC
from collections import deque

N = int(input())
edge = [[] for _ in range(N)]
for n in range(N - 1):
    a,b = map(int, input().split())
    edge[a-1].append([b-1, n])
    edge[b-1].append([a-1, n])

def bfs(s:int, g:int):
    """ 始点sから終点gまでのパスを求める """
    path = [0] * N
    visited = [False] * N
    flag = False # 終点到着フラグ
    
    que = deque([s])
    visited[s] = True
    while que:
        v = que.popleft()
        for w, n in edge[v]:
            if visited[w]: continue
            path[w] = path[v] | (1 << n) # パスを記録
            if w == g: # 終点到着
                flag = True
                break
            que.append(w)
        if flag: break
    return path[g]

def main():
    M = int(input())
    path = [0] * M # 各制約で使用するパス
    for i in range(M):
        u,v = map(int, input().split())
        path[i] = bfs(u - 1, v - 1)

    ans = 0
    # 包除原理
    for bit in range(1 << M):
        val = 0
        for i in range(M):
            if (bit >> i) & 1:
                val |= path[i]
        if bin(bit).count("1") % 2 == 0:
            ans += 1 << (N - 1 - bin(val).count("1"))
        else:
            ans -= 1 << (N - 1 - bin(val).count("1"))

    print(ans)

if __name__ == "__main__":
    main()

Submission status: Time Limit Exceeded

Solution code:
# 解説AC
from collections import deque

N = int(input())
edge = [[] for _ in range(N)]
for n in range(N - 1):
    a,b = map(int, input().split())
    edge[a-1].append([b-1, n])
    edge[b-1].append([a-1, n])

def bfs(s:int, g:int):
    """ 始点sから終点gまでのパスを求める """
    path = [0] * N
    visited = [False] * N
    flag = False # 終点到着フラグ
    
    que = deque([s])
    visited[s] = True
    while que:
        v = que.popleft()
        for w, n in edge[v]:
            if visited[w]: continue
            path[w] = path[v] | (1 << n) # パスを記録
            if w == g: # 終点到着
                flag = True
                break
            que.append(w)
        if flag: break
    return path[g]

M = int(input())
path = [0] * M # 各制約で使用するパス
for i in range(M):
    u,v = map(int, input().split())
    path[i] = bfs(u - 1, v - 1)

ans = 0
# 包除原理
for bit in range(1 << M):
    val = 0
    for i in range(M):
        if (bit >> i) & 1:
            val |= path[i]
    if bin(bit).count("1") % 2 == 0:
        ans += 1 << (N - 1 - bin(val).count("1"))
    else:
        ans -= 1 << (N - 1 - bin(val).count("1"))

print(ans)

Submission status: Time Limit Exceeded

Solution code:

def popcount(x):
    x = x - ((x >> 1) & 0x5555555555555555)
    x = (x & 0x3333333333333333) + ((x >> 2) & 0x3333333333333333)
    x = (x + (x >> 4)) & 0x0f0f0f0f0f0f0f0f
    x = x + (x >> 8)
    x = x + (x >> 16)
    x = x + (x >> 32)
    return x & 0x0000007f


def main():
    import collections
    N = int(input())
    G = [[-1]*N for i in range(N)]

    ans = 2**(N-1)
    for i in range(N-1):
        a, b = map(int, input().split())
        a -= 1
        b -= 1
        G[a][b] = i
        G[b][a] = i
    ans = 0
    g = [[0]*N for i in range(N)]
    for i in range(N):
        q = collections.deque()
        q.append((i, 0))
        r = [True]*N
        r[i] = False
        while(q):
            x, s = q.popleft()
            for y in range(N):
                if G[x][y] >= 0 and r[y]:
                    g[i][y] = s | 1 << G[x][y]
                    q.append((y, g[i][y]))
                    r[y] = False
    M = int(input())
    s = [0 for i in range(M)]
    for i in range(M):
        u, v = map(int, input().split())
        u -= 1
        v -= 1

        s[i] = g[u][v]

    # print(s)
    for i in range(2**M):
        tmp = 2**(N-1) - 1
        c = 0
        for j in range(M):
            if (i >> j) % 2 == 1:
                tmp &= ~s[j]
                c += 1
        ans += ((-1)**(c))*(1 << popcount(tmp))

    print(ans)


main()

Submission status: Time Limit Exceeded

Solution code:
#!usr/bin/env python3
from collections import defaultdict, deque
from heapq import heappush, heappop
from itertools import permutations, accumulate
import sys
import math
import bisect
def LI(): return [int(x) for x in sys.stdin.buffer.readline().split()]
def I(): return int(sys.stdin.buffer.readline())
def LS():return [list(x) for x in sys.stdin.readline().split()]
def S():
    res = list(sys.stdin.readline())
    if res[-1] == "\n":
        return res[:-1]
    return res
def IR(n):
    return [I() for i in range(n)]
def LIR(n):
    return [LI() for i in range(n)]
def SR(n):
    return [S() for i in range(n)]
def LSR(n):
    return [LS() for i in range(n)]

sys.setrecursionlimit(1000000)
mod = 1000000007

def solve():
    n = I()
    e = defaultdict(lambda : 0)
    v = [[] for i in range(n)]
    for i in range(n-1):
        a,b = LI()
        a -= 1
        b -= 1
        v[a].append(b)
        v[b].append(a)
        e[(a,b)] = e[(b,a)] = 1<<i
    d = [None]*n
    d[0] = 0
    q = [0]
    while q:
        x = q.pop()
        for y in v[x]:
            if d[y] is None:
                d[y] = d[x]|e[(x,y)]
                q.append(y)
    m = I()
    f = []
    for _ in range(m):
        a,b = LI()
        a -= 1
        b -= 1
        f.append(d[a]^d[b])
    ans = 0
    for b in range(1,1<<m):
        c = -1
        s = 0
        for i in range(m):
            if b&(1<<i):
                c *= -1
                s |= f[i]
        k = sum(map(int, bin(s)[2:]))
        ans += c*(1<<(n-1-k))
    print((1<<n-1)-ans)
    return

#Solve
if __name__ == "__main__":
    solve()

Submission status: Time Limit Exceeded

Solution code:
#!usr/bin/env python3
from collections import defaultdict, deque
from heapq import heappush, heappop
from itertools import permutations, accumulate
import sys
import math
import bisect
def LI(): return [int(x) for x in sys.stdin.buffer.readline().split()]
def I(): return int(sys.stdin.buffer.readline())
def LS():return [list(x) for x in sys.stdin.readline().split()]
def S():
    res = list(sys.stdin.readline())
    if res[-1] == "\n":
        return res[:-1]
    return res
def IR(n):
    return [I() for i in range(n)]
def LIR(n):
    return [LI() for i in range(n)]
def SR(n):
    return [S() for i in range(n)]
def LSR(n):
    return [LS() for i in range(n)]

sys.setrecursionlimit(1000000)
mod = 1000000007

def solve():
    n = I()
    e = defaultdict(lambda : 0)
    v = [[] for i in range(n)]
    for i in range(n-1):
        a,b = LI()
        a -= 1
        b -= 1
        v[a].append(b)
        v[b].append(a)
        e[(a,b)] = e[(b,a)] = 1<<i
    d = [None]*n
    d[0] = 0
    q = [0]
    while q:
        x = q.pop()
        for y in v[x]:
            if d[y] is None:
                d[y] = d[x]|e[(x,y)]
                q.append(y)
    m = I()
    f = []
    for _ in range(m):
        a,b = LI()
        a -= 1
        b -= 1
        f.append(d[a]^d[b])
    ans = 0
    for b in range(1,1<<m):
        c = -1
        s = 0
        for i in range(m):
            if b&(1<<i):
                c *= -1
                s |= f[i]
        k = sum(map(int, bin(s)[2:]))
        ans += c*((1<<k)-1)*(1<<(n-1-k))
    print(ans)
    return

#Solve
if __name__ == "__main__":
    solve()

Submission status: Time Limit Exceeded

Solution code:
#!usr/bin/env python3
from collections import defaultdict, deque
from heapq import heappush, heappop
from itertools import permutations, accumulate
import sys
import math
import bisect
def LI(): return [int(x) for x in sys.stdin.buffer.readline().split()]
def I(): return int(sys.stdin.buffer.readline())
def LS():return [list(x) for x in sys.stdin.readline().split()]
def S():
    res = list(sys.stdin.readline())
    if res[-1] == "\n":
        return res[:-1]
    return res
def IR(n):
    return [I() for i in range(n)]
def LIR(n):
    return [LI() for i in range(n)]
def SR(n):
    return [S() for i in range(n)]
def LSR(n):
    return [LS() for i in range(n)]

sys.setrecursionlimit(1000000)
mod = 1000000007

def solve():
    n = I()
    e = defaultdict(lambda : 0)
    v = [[] for i in range(n)]
    for i in range(n-1):
        a,b = LI()
        a -= 1
        b -= 1
        v[a].append(b)
        v[b].append(a)
        e[(a,b)] = e[(b,a)] = 1<<i
    d = [None]*n
    d[0] = 0
    q = [0]
    while q:
        x = q.pop()
        for y in v[x]:
            if d[y] is None:
                d[y] = d[x]|e[(x,y)]
                q.append(y)
    m = I()
    f = []
    for _ in range(m):
        a,b = LI()
        a -= 1
        b -= 1
        f.append((a,b))
    ans = 0
    for b in range(1,1<<m):
        c = -1
        s = 0
        for i in range(m):
            if b&(1<<i):
                c *= -1
                x,y = f[i]
                s |= d[x]^d[y]
        k = sum(map(int, bin(s)[2:]))
        ans += c*((1<<k)-1)*(1<<(n-1-k))
    print(ans)
    return

#Solve
if __name__ == "__main__":
    solve()

Submission status: Time Limit Exceeded

Solution code:
#!usr/bin/env python3
from collections import defaultdict, deque
from heapq import heappush, heappop
from itertools import permutations, accumulate
import sys
import math
import bisect
def LI(): return [int(x) for x in sys.stdin.buffer.readline().split()]
def I(): return int(sys.stdin.buffer.readline())
def LS():return [list(x) for x in sys.stdin.readline().split()]
def S():
    res = list(sys.stdin.readline())
    if res[-1] == "\n":
        return res[:-1]
    return res
def IR(n):
    return [I() for i in range(n)]
def LIR(n):
    return [LI() for i in range(n)]
def SR(n):
    return [S() for i in range(n)]
def LSR(n):
    return [LS() for i in range(n)]

sys.setrecursionlimit(1000000)
mod = 1000000007

def solve():
    n = I()
    ns = set()
    v = [[] for i in range(n)]
    for _ in range(n-1):
        a,b = LI()
        a -= 1
        b -= 1
        v[a].append(b)
        v[b].append(a)
        ns.add((min(a,b),max(a,b)))
    d = [None]*n
    d[0] = set()
    q = [0]
    while q:
        x = q.pop()
        for y in v[x]:
            if d[y] is None:
                d[y] = d[x]|{(min(x,y),max(x,y))}
                q.append(y)
    m = I()
    f = []
    for _ in range(m):
        a,b = LI()
        a -= 1
        b -= 1
        f.append((a,b))
    ans = 0
    for b in range(1,1<<m):
        c = -1
        s = set()
        for i in range(m):
            if b&(1<<i):
                c *= -1
                x,y = f[i]
                s |= d[x]^d[y]
        ans += c*((1<<len(s))-1)*(1<<(n-1-len(s)))
    print(ans)
    return

#Solve
if __name__ == "__main__":
    solve()

Submission status: Time Limit Exceeded

Solution code:
from scipy.sparse.csgraph import csgraph_from_dense, floyd_warshall
N = int(input())
G = [[-1]*N for i in range(N)]


def get_path(start, goal, pred):
    return get_path_row(start, goal, pred[start])


def get_path_row(start, goal, pred_row):
    path = []
    i = goal
    while i != start and i >= 0:
        path.append(i)
        i = pred_row[i]
    if i < 0:
        return []
    path.append(i)
    return path[::-1]


ans = 2**(N-1)
for i in range(N-1):
    a, b = map(int, input().split())
    a -= 1
    b -= 1
    G[a][b] = 1
    G[b][a] = 1
G = csgraph_from_dense(G, null_value=-1)
g, p = floyd_warshall(G, return_predecessors=True)
ans = 0
# print(g)
M = int(input())
s = [set() for i in range(M)]
for i in range(M):
    u, v = map(int, input().split())
    u -= 1
    v -= 1
    gp = get_path(u, v, p)
    for j in range(len(gp)-1):
        s[i].add((min(gp[j], gp[j+1]), max(gp[j], gp[j+1])))

for i in range(2**M):
    tmp = set()
    c = 0
    for j in range(M):
        if (i >> j) % 2 == 1:
            tmp |= s[j]
            c += 1

    ans += ((-1)**c)*(2**(N-1 - len(tmp)))


print(ans)

Submission status: Time Limit Exceeded

Solution code:
from itertools import product

n = int(input())
ab = [list(map(int, input().split())) for _ in range(n - 1)]
m = int(input())
uv = [list(map(int, input().split())) for _ in range(m)]

adj = [[] for _ in range(n)]
ids = [[-1] * n for _ in range(n)]
for i, (a, b) in enumerate(ab):
    a -= 1
    b -= 1
    adj[a].append(b)
    adj[b].append(a)
    ids[a][b] = i
    ids[b][a] = i


def dfs(s, g):
    d = [-1] * n
    d[s] = 0
    p = [-1] * n
    stack = [s]

    while stack:
        u = stack.pop()
        for v in adj[u]:
            if d[v] == -1:
                d[v] = d[u] + 1
                p[v] = u
                stack.append(v)

    v = g
    ret = 0
    while v != s:
        i = ids[v][p[v]]
        ret += 1 << i
        v = p[v]

    return ret


path = [dfs(u - 1, v - 1) for u, v in uv]
ans = 0
for tpl in product([1, 0], repeat=m):
    coef = 1
    cnt = 0
    for bl, e in zip(tpl, path):
        if bl:
            cnt |= e
            coef *= -1
    ans += pow(2, n - 1 - bin(cnt).count("1")) * coef

print(ans)

Submission status: Time Limit Exceeded

Solution code:
#!/usr/bin/env python3
from collections import defaultdict,deque
from heapq import heappush, heappop
from bisect import bisect_left, bisect_right
import sys, random, itertools, math
sys.setrecursionlimit(10**5)
input = sys.stdin.readline
sqrt = math.sqrt
def LI(): return list(map(int, input().split()))
def LF(): return list(map(float, input().split()))
def LI_(): return list(map(lambda x: int(x)-1, input().split()))
def II(): return int(input())
def IF(): return float(input())
def LS(): return list(map(list, input().split()))
def S(): return list(input().rstrip())
def IR(n): return [II() for _ in range(n)]
def LIR(n): return [LI() for _ in range(n)]
def FR(n): return [IF() for _ in range(n)]
def LFR(n): return [LI() for _ in range(n)]
def LIR_(n): return [LI_() for _ in range(n)]
def SR(n): return [S() for _ in range(n)]
def LSR(n): return [LS() for _ in range(n)]
mod = 1000000007
inf = 1e10

#solve
def solve():
    n = II()
    edg = [[] for i in range(n)]
    t = 0
    ab = defaultdict(int)
    d = defaultdict(int)
    for _ in range(n - 1):
        a, b = LI_()
        edg[a].append(b)
        edg[b].append(a)
        d[(a, b)] = t
        d[(b, a)] = t
        t += 1
    m = II()
    path = [0] * m 
    uv = LIR_(m)
    for i, uvi in enumerate(uv):
        u, v = uvi
        q = deque()
        q.append((u, []))
        while q:
            p, pat = q.popleft()
            for e in edg[p]:
                if e in pat:
                    continue
                if e == v:
                    pat += [d[(p, e)]]
                    q = deque()
                    break
                else:
                    q.append((e, pat + [d[(p, e)]]))
        for p in pat:
            path[i] |= 1 << p
    ans = 1 << (n-1)
    for mask in range(1, 1 << m):
        tmp = 0
        t = 0
        for i in range(m):
            if mask & (1 << i):
                t += 1
                tmp = tmp | path[i]
        x = 0
        while tmp:
            x += tmp & 1
            tmp >>=1
        ans += (1 << (n - x - 1)) * (-1) ** t
    print(ans)


    return


#main
if __name__ == '__main__':
    solve()

Submission status: Time Limit Exceeded

Solution code:
#!/usr/bin/env python3
from collections import defaultdict,deque
from heapq import heappush, heappop
from bisect import bisect_left, bisect_right
import sys, random, itertools, math
sys.setrecursionlimit(10**5)
input = sys.stdin.readline
sqrt = math.sqrt
def LI(): return list(map(int, input().split()))
def LF(): return list(map(float, input().split()))
def LI_(): return list(map(lambda x: int(x)-1, input().split()))
def II(): return int(input())
def IF(): return float(input())
def LS(): return list(map(list, input().split()))
def S(): return list(input().rstrip())
def IR(n): return [II() for _ in range(n)]
def LIR(n): return [LI() for _ in range(n)]
def FR(n): return [IF() for _ in range(n)]
def LFR(n): return [LI() for _ in range(n)]
def LIR_(n): return [LI_() for _ in range(n)]
def SR(n): return [S() for _ in range(n)]
def LSR(n): return [LS() for _ in range(n)]
mod = 1000000007
inf = 1e10

#solve
def solve():
    n = II()
    edg = [[] for i in range(n)]
    t = 0
    ab = defaultdict(int)
    d = defaultdict(int)
    for _ in range(n - 1):
        a, b = LI_()
        edg[a].append(b)
        edg[b].append(a)
        d[(a, b)] = t
        d[(b, a)] = t
        t += 1
    m = II()
    path = [None] * m 
    uv = LIR_(m)
    for i, uvi in enumerate(uv):
        u, v = uvi
        q = deque()
        q.append((u, []))
        while q:
            p, pat = q.popleft()
            for e in edg[p]:
                if e in pat:
                    continue
                if e == v:
                    pat += [d[(p, e)]]
                    q = deque()
                    break
                else:
                    q.append((e, pat + [d[(p, e)]]))
        path[i] = set(pat)
    ans = 1 << (n-1)
    for mask in range(1, 1 << m):
        tmp = set()
        t = 0
        for i in range(m):
            if mask & (1 << i):
                t += 1
                tmp = tmp | path[i]
        ans += (1 << (n - len(tmp) - 1)) * (-1) ** t
    print(ans)


    return


#main
if __name__ == '__main__':
    solve()

Submission status: Time Limit Exceeded

Solution code:
import sys
sys.setrecursionlimit(10000000)
def input():
    return sys.stdin.readline()[:-1]
from math import log
from bisect import *
from collections import *
from heapq import *
mod = 10**9+7

def popcnt(n):
    c = (n & 0x5555555555555555) + ((n>>1) & 0x5555555555555555)
    c = (c & 0x3333333333333333) + ((c>>2) & 0x3333333333333333)
    c = (c & 0x0f0f0f0f0f0f0f0f) + ((c>>4) & 0x0f0f0f0f0f0f0f0f)
    c = (c & 0x00ff00ff00ff00ff) + ((c>>8) & 0x00ff00ff00ff00ff)
    c = (c & 0x0000ffff0000ffff) + ((c>>16) & 0x0000ffff0000ffff)
    c = (c & 0x00000000ffffffff) + ((c>>32) & 0x00000000ffffffff)
    return c

N = int(input())
edges = [[] for i in range(N)]
edge_id = defaultdict(lambda : -1)
for i in range(N-1):
    a, b = map(lambda x: int(x)-1, input().split())
    edges[a].append(b)
    edges[b].append(a)
    edge_id[(a, b)] = edge_id[(b, a)] = i
path = defaultdict(lambda : -1)

def set_path(r, v, path_):
    visited[v] = 1
    path[(r, v)] = path_
    for u in edges[v]:
        if visited[u] == 0:
            set_path(r, u, path_ | (1 << edge_id[(v, u)]))

for i in range(N):
    visited = [0] * N
    set_path(i, i, 0)
M = int(input())
uv = [list(map(lambda x: int(x)-1, input().split())) for i in range(M)]
ans = pow(2, N-1)
for i in range(1, 1 << M):
    all_path = 0
    for j, (u, v) in enumerate(uv):
        if i & (1 << j):
            all_path |= path[(u, v)]
    if popcnt(i) & 1:
        ans -= pow(2, N-1-popcnt(all_path))
    else:
        ans += pow(2, N-1-popcnt(all_path))
print(ans)