Problem:


E : Arojam&#39;s Mask / 仮面

問題文

あなたは勇者である。勇者が旅をしている世界は N 個の街と、異なる街同士を結ぶ M 本の道からなる。道 i は街 a_i と街 b_i を結び、双方向に移動可能である。

街 S から出発し、街 T に移動することが勇者の目的である。 S,T は異なる街である。勇者は 0 日目に街を出発し、ちょうど 1 日かけて 1 本の道を通って移動することができる。道を使った移動には日数の制限 R があり、R 日目を超えることはできない。

また、勇者は任意の街で「オカリナを吹く」こともできる。オカリナを吹くと、時は 0 日目に、位置は街 S に戻される。つまり、R 回を超える移動を行う場合は、最低一度はオカリナを吹かなければならない。

さらに、勇者がある街に位置すると「イベント」が発生することがある。イベントは E 種類あり、i 番目のイベントは、街 c_{i} で発生する。イベントは勇者がそこにいると自動的に発生し、新たに道 a’_i と b’_i を結ぶ道が生じる。この道はオカリナを吹いても消えることはなく、初めから存在する道とも、別のイベントによって追加される道とも重複しない。ある町で起こるイベントは高々1つである。

さて、勇者の今日の仕事は、街 T に到達するまでに必要な移動の回数とオカリナを吹く回数の和の最小値を求めるプログラムを書くことである。

入力

入力は以下の形式で与えられる。

N M E S T R
a_{0} b_{0}
…
a_{M&minus;1} b_{M&minus;1}
a’_{0} b’_{0} c_{0}
…
a’_{E&minus;1} b’_{E&minus;1} c_{E&minus;1}

制約

入力はすべて整数である

2 \≤ N \≤ 100

1 \≤ M+E \≤ N(N&minus;1)/2

0 \≤ E \≤ 4

0 \≤ R \≤ 100

0 \≤ S,T,a_i,b_i,a’_i,b’_i,c_i \≤ N&minus;1

S ≠ T

a_{i} ≠ b_{i}, a’_{i} ≠ b’_{i}

a_{i} と b_{i}、a’_{i} と b’_{i}の全ての組は重複しない

i ≠ j なら c_{i} ≠ c_{j}

出力

答えを一行で出力せよ。どうしても T へ到達できない場合は &minus;1 を出力せよ。

サンプル

サンプル入力1

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

サンプル出力1

9

例えば以下のように移動すればよい。イベントを起こすまでは道(4,5), (3,4)は存在しないことに注意せよ。

街2に行くと4から5へ移動できるようになる

オカリナを使用し0へ戻る

街7に行くと3から4へ移動できるようになる

オカリナを使用し0へ戻る

0から5へまっすぐ進む

サンプル入力2

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

サンプル出力2

8

オカリナを1度も吹かない経路が最適である。

サンプル入力3

4 1 4 1 2 3
3 1
3 2 0
0 1 3
0 3 1
0 2 2

サンプル出力3

5

街 S でイベントが起こることもある。


Sample input:
8 5 2 0 5 5
0 1
0 3
0 6
1 2
6 7
3 4 7
4 5 2


Sample output:
9

Submission status: Wrong Answer

Solution code:
import copy
inf = 10**9
N,M,E,S,T,R = map(int,raw_input().split())

G = [[inf]*N for i in xrange(N)]
for loop in xrange(M):
    a,b = map(int,raw_input().split())
    G[a][b] = G[b][a] = 1

event = [[] for i in xrange(N)]
for loop in xrange(E):
    a,b,c = map(int,raw_input().split())
    event[c] = [a,b]

if event[S]:
    a,b = event[S]
    G[a][b] = G[b][a] = 1
    que = [[S,0,set([S]),0,G]]
else:
    que = [[S,0,set([]),0,G]]
    
while que:
    p,r,e,d,g = que.pop(0)
    if p == T:
        print d
        break
    if r > R and (not event[p] or p in e):
        continue
    for i in xrange(N):
        if g[p][i] == 1:
            if event[i] and i not in e:
                ng = copy.deepcopy(g)
                a,b = event[i]
                ng[a][b] = ng[b][a] = 1
                que.append([S,0,e|set([i]),d+2,ng])
                que.append([i,r+1,e|set([i]),d+1,ng])
            else:
                que.append([i,r+1,e,d+1,copy.deepcopy(g)])

Submission status: Wrong Answer

Solution code:
import copy
inf = 10**9
N,M,E,S,T,R = map(int,raw_input().split())

G = [[inf]*N for i in xrange(N)]
for loop in xrange(M):
    a,b = map(int,raw_input().split())
    G[a][b] = G[b][a] = 1

event = [[] for i in xrange(N)]
for loop in xrange(E):
    a,b,c = map(int,raw_input().split())
    event[c] = [a,b]

if event[S]:
    a,b = event[S]
    G[a][b] = G[b][a] = 1
    que = [[S,0,set([S]),0,G]]
else:
    que = [[S,0,set([]),0,G]]

ans = inf
while que:
    p,r,e,d,g = que.pop(0)
    if p == T:
        ans = min(ans,d)
        continue
    if ans <= d-2 or r >= R and (not event[p] or p in e):
        continue
    for i in xrange(N):
        if g[p][i] == 1:
            if event[i] and i not in e:
                ng = copy.deepcopy(g)
                a,b = event[i]
                ng[a][b] = ng[b][a] = 1
                que.append([S,  0,e|set([i]),d+2,ng])
                que.append([i,r+1,e|set([i]),d+1,ng])
            else:
                que.append([i,r+1,e,d+1,g])
print ans

Submission status: Wrong Answer

Solution code:
import copy
inf = 10**9
N,M,E,S,T,R = map(int,raw_input().split())

G = [[inf]*N for i in xrange(N)]
for loop in xrange(M):
    a,b = map(int,raw_input().split())
    G[a][b] = G[b][a] = 1

event = [[] for i in xrange(N)]
for loop in xrange(E):
    a,b,c = map(int,raw_input().split())
    event[c] = [a,b]

if event[S]:
    a,b = event[S]
    G[a][b] = G[b][a] = 1
    que = [[S,0,set([S]),0,G]]
else:
    que = [[S,0,set([]),0,G]]

ans = inf
while que:
    p,r,e,d,g = que.pop(0)
    if p == T:
        ans = min(ans,d)
        continue
    if ans < d or r >= R:
        continue
    for i in xrange(N):
        if g[p][i] == 1:
            if event[i] and i not in e:
                ng = copy.deepcopy(g)
                a,b = event[i]
                ng[a][b] = ng[b][a] = 1
                que.append([S,  0,e|set([i]),d+2,ng])
                que.append([i,r+1,e|set([i]),d+1,ng])
            else:
                que.append([i,r+1,e,d+1,g])
print ans

Submission status: Wrong Answer

Solution code:
import copy
inf = 10**9
N,M,E,S,T,R = map(int,raw_input().split())

G = [[inf]*N for i in xrange(N)]
for loop in xrange(M):
    a,b = map(int,raw_input().split())
    G[a][b] = G[b][a] = 1

event = [[] for i in xrange(N)]
for loop in xrange(E):
    a,b,c = map(int,raw_input().split())
    event[c] = [a,b]

if event[S]:
    a,b = event[S]
    G[a][b] = G[b][a] = 1
    que = [[S,0,set([S]),0,G]]
else:
    que = [[S,0,set([]),0,G]]

ans = inf
while que:
    p,r,e,d,g = que.pop(0)

    if ans < d or r >= R:
        continue
    for i in xrange(N):
        if g[p][i] == 1:
            if i == T:
                ans = min(ans,d+1)
                break
            if event[i] and i not in e:
                ng = copy.deepcopy(g)
                a,b = event[i]
                ng[a][b] = ng[b][a] = 1
                que.append([S,  0,e|set([i]),d+2,ng])
                que.append([i,r+1,e|set([i]),d+1,ng])
            else:
                que.append([i,r+1,e,d+1,g])
print ans

Submission status: Wrong Answer

Solution code:
import copy
inf = 10**9
N,M,E,S,T,R = map(int,raw_input().split())

G = [[inf]*N for i in xrange(N)]
for loop in xrange(M):
    a,b = map(int,raw_input().split())
    G[a][b] = G[b][a] = 1

event = [[] for i in xrange(N)]
for loop in xrange(E):
    a,b,c = map(int,raw_input().split())
    event[c] = [a,b]

if event[S]:
    a,b = event[S]
    G[a][b] = G[b][a] = 1
    que = [[S,0,0,set([S]),0,G]]
else:
    que = [[S,0,0,set([]),0,G]]

ans = inf
while que:
    cur,bef,r,e,d,g = que.pop(0)

    if ans < d or r >= R:
        continue
    for i in xrange(N):
        if g[cur][i] == 1:
            if i == T:
                ans = min(ans,d+1)
                break
            if event[i] and i not in e:
                ng = copy.deepcopy(g)
                a,b = event[i]
                ng[a][b] = ng[b][a] = 1
                que.append([S,  0,  0,e|set([i]),d+2,ng])
                que.append([i,cur,r+1,e|set([i]),d+1,ng])
            else:
                if i == bef: continue
                que.append([i,cur,r+1,e,d+1,g])

print ans if ans < inf else -1

Submission status: Time Limit Exceeded

Solution code:
import copy
inf = 10**9
N,M,E,S,T,R = map(int,raw_input().split())

G = [[inf]*N for i in xrange(N)]
for loop in xrange(M):
    a,b = map(int,raw_input().split())
    G[a][b] = G[b][a] = 1

event = [[] for i in xrange(N)]
for loop in xrange(E):
    a,b,c = map(int,raw_input().split())
    event[c] = [a,b]

if event[S]:
    a,b = event[S]
    G[a][b] = G[b][a] = 1
    que = [[S,0,set([S]),0,G]]
else:
    que = [[S,0,set([]),0,G]]

ans = inf
while que:
    p,r,e,d,g = que.pop(0)

    if ans < d or r >= R:
        continue
    for i in xrange(N):
        if g[p][i] == 1:
            if i == T:
                ans = min(ans,d+1)
                break
            if event[i] and i not in e:
                ng = copy.deepcopy(g)
                a,b = event[i]
                ng[a][b] = ng[b][a] = 1
                que.append([S,  0,e|set([i]),d+2,ng])
                que.append([i,r+1,e|set([i]),d+1,ng])
            else:
                que.append([i,r+1,e,d+1,g])

print ans if ans < inf else -1

Submission status: Accepted

Solution code:
import sys
from heapq import heappush,heappop
from collections import defaultdict
MA = 10000
def dijkstra(s,g):
    d = defaultdict(lambda : MA)
    q = [(0,s,1,0)]
    d[(s,1,0)] = 0
    while q:
        dx,x,b,day = heappop(q)
        day_ = day+1
        if eve[x] > 0:
            b = b|(1<<eve[x])
            if dx+1 < d[(s,b,0)]:
                d[(s,b,0)] = dx+1
                heappush(q,(d[(s,b,0)],s,b,0))
        if day_ <= r:
            for i in range(e):
                if (1<<i)&b:
                    for y in v[x][i]:
                        dist = dx+1
                        if dist < d[(y,b,day_)]:
                            d[(y,b,day_)] = dist
                            heappush(q,(d[(y,b,day_)],y,b,day_))
    res = MA
    for i in range(1<<e):
        for day in range(r+1):
            res = min(res,d[(g,i,day)])
    if res == MA:
        res = -1
    return res

n,m,e,s,t,r = [int(x) for x in sys.stdin.readline().split()]
v = [[[] for i in range(e+1)] for i in range(n)]
for i in range(m):
    a,b = [int(x) for x in sys.stdin.readline().split()]
    v[a][0].append(b)
    v[b][0].append(a)
eve = [0 for i in range(n)]

for i in range(e):
    a,b,c = [int(x) for x in sys.stdin.readline().split()]
    eve[c] = i+1
    v[a][i+1].append(b)
    v[b][i+1].append(a)
e += 1
print(dijkstra(s,t))

Submission status: Accepted

Solution code:
from collections import deque

n, m, e, s, t, r = map(int, input().split())
edges = [[] for _ in range(n * 2 ** e)]
for _ in range(m):
  a, b = map(int, input().split())
  for i in range(2 ** e):
    edges[a + n * i].append(b + n * i)
    edges[b + n * i].append(a + n * i)

start = s
slide = {}
for i in range(e):
  a, b, c = map(int, input().split())
  slide[c] = 2 ** i
  if c == s:
    start = s + n * 2 ** i
  mask = 2 ** i
  for j in range(2 ** e):
    if mask & j:continue
    edges[a + n * (mask | j)].append(b + n * (mask | j))
    edges[b + n * (mask | j)].append(a + n * (mask | j))

goal = {t + n * i for i in range(2 ** e)}
dist = {}
dist[(start, 0)] = 0
que = deque()
que.append((0, 0, start))
while que:
  score, acc, node = que.popleft()
  if node in goal:
    print(score)
    break
  
  level = node // n
  if (s + n * level, 0) not in dist:
    dist[(s + n * level, 0)] = score + 1
    que.append((score + 1, 0, s + n * level))
  
  if acc == r:continue 
  for to in edges[node]:
    if to % n in slide:to = to % n + n * (to // n | slide[to % n])
    if (to, acc + 1) not in dist:
      dist[(to, acc + 1)] = score + 1
      que.append((score + 1, acc + 1, to))

else:
  print(-1)