1116 - Karb: Difference between revisions

From Bitnami MediaWiki
 
(2 intermediate revisions by the same user not shown)
Line 1: Line 1:
== Enunt ==
== Enunt ==
În perioada Campionatului Mondial din Brazilia se preconizează o creştere a traficului de cafea. Se ştie că sunt N orase, conectate prin N-1 străzi bidirecţionale, astfel încât se poate ajunge din orice oraş în altul. În prezent există K carteluri de cafea aflate în oraşe distincte, care își exercita influența în propriul oraș. Se ştie că fiecare din aceste carteluri doreşte să-şi extindă influenţa în oraşele vecine. Astfel, la un moment de timp, un cartel poate să-şi extindă influenţa într-un oraş vecin doar dacă acesta nu se află sub influenţa altui cartel. O dată ce un cartel îşi extinde influenta asupra unui nou oraş, cartelul îşi poate extinde influenţa şi în oraşele vecine acestuia. Se ştie că până la începerea campionatului mondial, fiecare oraş va fi sub influenţa unui cartel.
În perioada Campionatului Mondial din Brazilia se preconizează o creştere a traficului de cafea. Se ştie că sunt '''N''' orase, conectate prin '''N-1''' străzi bidirecţionale, astfel încât se poate ajunge din orice oraş în altul. În prezent există '''K''' carteluri de cafea aflate în oraşe distincte, care își exercita influența în propriul oraș. Se ştie că fiecare din aceste carteluri doreşte să-şi extindă influenţa în oraşele vecine. Astfel, la un moment de timp, un cartel poate să-şi extindă influenţa într-un oraş vecin doar dacă acesta nu se află sub influenţa altui cartel. O dată ce un cartel îşi extinde influenta asupra unui nou oraş, cartelul îşi poate extinde influenţa şi în oraşele vecine acestuia. Se ştie că până la începerea campionatului mondial, fiecare oraş va fi sub influenţa unui cartel.


ABIN (Agência Brasileira de Inteligência) doreşte să afle în câte moduri poate fi dominată ţara de influenţele celor K carteluri la data începerii campionatului mondial, modulo 666013.
ABIN (Agência Brasileira de Inteligência) doreşte să afle în câte moduri poate fi dominată ţara de influenţele celor '''K''' carteluri la data începerii campionatului mondial, modulo '''666013'''.


== Cerință ==
== Cerință ==
Cunoscând numărul de orașe N, modul în care acestea sunt conectate, numărul de carteluri inițiale K și cele K orașe în care se află cartelurile, să se determine numărul de moduri în care ţara poate fi împărţită între cartelurile de cafea, modulo 666013.
Cunoscând numărul de orașe '''N''', modul în care acestea sunt conectate, numărul de carteluri inițiale '''K''' și cele '''K''' orașe în care se află cartelurile, să se determine numărul de moduri în care ţara poate fi împărţită între cartelurile de cafea, modulo '''666013'''.


== Date de intrare ==
== Date de intrare ==
Fișierul de intrare karbin.txt conține pe prima linie două numere naturale N şi K, reprezentând numărul de oraşe, respectiv numărul cartelurilor existente iniţial. Pe a doua linie din fişier se vor afla K numere, reprezentând oraşele în care se află cele K carteluri. Pe următoarele N-1 linii se vor afla câte două numere naturale, reprezentând o legătură între cele două oraşe.
Fișierul de intrare '''karbin.txt''' conține pe prima linie două numere naturale '''N''' şi '''K''', reprezentând numărul de oraşe, respectiv numărul cartelurilor existente iniţial. Pe a doua linie din fişier se vor afla '''K''' numere, reprezentând oraşele în care se află cele '''K''' carteluri. Pe următoarele '''N-1''' linii se vor afla câte două numere naturale, reprezentând o legătură între cele două oraşe.


== Date de ieșire ==
== Date de ieșire ==
Fișierul de ieșire karbout.txt va conține pe prima linie un singur număr natural reprezentând numărul de moduri modulo 666013.
Fișierul de ieșire '''karbout.txt''' va conține pe prima linie un singur număr natural reprezentând numărul de moduri modulo '''666013'''.


== Restricții și precizări ==
== Restricții și precizări ==
*1 ⩽ K ⩽ N ⩽ 100 000
*'''1 ⩽ K ⩽ N ⩽ 100 000'''
*Pentru teste în valoare de 10% din punctaj se garantează că k n 7, iar pentru alte 20% din teste se garantează că k = 2.
*Pentru teste în valoare de 10% din punctaj se garantează că '''k ⩽ n ⩽ 7''', iar pentru alte 20% din teste se garantează că '''k = 2'''.
*Două oraşe sunt vecine dacă există o stradă bidirecțională între ele.
*Două oraşe sunt vecine dacă există o stradă bidirecțională între ele.
== Exemplu 1 ==
== Exemplu 1 ==
;karbin.txt
;'''karbin.txt'''
:6 3
:6 3
:3 4 5
:3 4 5
Line 26: Line 26:
:2 5  
:2 5  
:4 6
:4 6
;karbout.txt
;'''karbout.txt'''
:5
:5
<br>
<br>
== Exemplu 2 ==
== Exemplu 2 ==
;karbin.txt
;'''karbin.txt'''
:0 0
:0 0
;karbout.txt
;'''karbout.txt'''
:Nu au fost respectate cerintele
:Nu au fost respectate cerintele
<br>
<br>
Line 38: Line 38:
<syntaxhighlight lang="python" line>
<syntaxhighlight lang="python" line>
#1116 - Karb
#1116 - Karb
MODULO = 666013
import sys


mod = 666013
maxdim = 200005


def check_restrictions(N, K, output_file):
def check_restrictions(n, k):
     if not (1 <= K <= N <= 100000):
     if not (1 <= k <= n <= 100000):
         output_file.write("Nu au fost respectate cerintele impuse\n")
         with open("karbout.txt", "w") as output_file:
         exit()
            output_file.write("Datele nu corespund restrictiilor impuse\n")
         sys.exit()


def dfs(nod):
    global D, T, special, viz, G


def count_ways_to_dominate(N, K, cartel_cities, connections):
     viz[nod] = 1
     adj_list = {i: [] for i in range(1, N + 1)}


     for conn in connections:
    sons = 0
         adj_list[conn[0]].append(conn[1])
     for fiu in G[nod]:
        adj_list[conn[1]].append(conn[0])
         if viz[fiu]:
            continue


    visited = [False] * (N + 1)
        sons += 1
    ways_to_dominate = [0] * (N + 1)
        T[fiu] = nod
        dfs(fiu)


     def dfs(node):
     if not sons:
         nonlocal ways_to_dominate
         if special[nod]:
            D[nod][0], D[nod][1] = 0, 1
        else:
            D[nod][0], D[nod][1] = 1, 0
        return


        visited[node] = True
    localD = [[0] * (sons + 1) for _ in range(2)]
         ways_to_dominate[node] = 1
    localD[0][0] = 1
    ind = 0
    for fiu in G[nod]:
         if T[fiu] != nod:
            continue


         for neighbor in adj_list[node]:
         ind += 1
            if not visited[neighbor]:
        localD[0][ind] = (localD[0][ind - 1] * (D[fiu][0] + D[fiu][1])) % mod
                dfs(neighbor)
        localD[1][ind] = (localD[0][ind - 1] * D[fiu][1] + localD[1][ind - 1] * (D[fiu][0] + D[fiu][1])) % mod
                ways_to_dominate[node] += ways_to_dominate[neighbor]
                ways_to_dominate[node] %= MODULO


     for city in cartel_cities:
     if not special[nod]:
         dfs(city)
         D[nod][0], D[nod][1] = localD[0][ind], localD[1][ind]
    else:
        D[nod][0], D[nod][1] = 0, localD[0][ind]


    total_ways = 1
def main():
     for city in cartel_cities:
     global D, T, special, viz, G
        total_ways *= ways_to_dominate[city]
        total_ways %= MODULO


     return total_ways
     input_file = open("karbin.txt", "r")
    output_file = open("karbout.txt", "w")


    # Citeste N si K
    N, K = map(int, input_file.readline().split())
   
    check_restrictions(N, K)


if _name_ == "_main_":
    special = [0] * maxdim
     with open("karbin.txt", "r") as input_file, open("karbout.txt", "w") as output_file:
    viz = [0] * maxdim
        N, K = map(int, input_file.readline().split())
     T = [0] * maxdim
    D = [[0] * 2 for _ in range(maxdim)]
    G = [[] for _ in range(maxdim)]


        check_restrictions(N, K, output_file)
    # Citeste orașele cu carteluri
    cartel_cities = list(map(int, input_file.readline().split()))
    assert len(cartel_cities) == K
    for x in cartel_cities:
        assert not special[x]
        assert 1 <= x <= N
        special[x] = x


         cartel_cities = list(map(int, input_file.readline().split()))
    # Citeste legăturile între orașe
         connections = [tuple(map(int, input_file.readline().split())) for _ in range(N - 1)]
    for _ in range(N - 1):
         x, y = map(int, input_file.readline().split())
        assert 1 <= x <= N
        assert 1 <= y <= N
        assert x != y
        G[x].append(y)
         G[y].append(x)
 
    dfs(1)
    print(D[1][1], file=output_file)
 
    input_file.close()
    output_file.close()
 
if __name__ == "__main__":
    main()


        result = count_ways_to_dominate(N, K, cartel_cities, connections)
        output_file.write(str(result - 1) + "\n")
</syntaxhighlight>
</syntaxhighlight>

Latest revision as of 16:51, 8 January 2024

Enunt[edit | edit source]

În perioada Campionatului Mondial din Brazilia se preconizează o creştere a traficului de cafea. Se ştie că sunt N orase, conectate prin N-1 străzi bidirecţionale, astfel încât se poate ajunge din orice oraş în altul. În prezent există K carteluri de cafea aflate în oraşe distincte, care își exercita influența în propriul oraș. Se ştie că fiecare din aceste carteluri doreşte să-şi extindă influenţa în oraşele vecine. Astfel, la un moment de timp, un cartel poate să-şi extindă influenţa într-un oraş vecin doar dacă acesta nu se află sub influenţa altui cartel. O dată ce un cartel îşi extinde influenta asupra unui nou oraş, cartelul îşi poate extinde influenţa şi în oraşele vecine acestuia. Se ştie că până la începerea campionatului mondial, fiecare oraş va fi sub influenţa unui cartel.

ABIN (Agência Brasileira de Inteligência) doreşte să afle în câte moduri poate fi dominată ţara de influenţele celor K carteluri la data începerii campionatului mondial, modulo 666013.

Cerință[edit | edit source]

Cunoscând numărul de orașe N, modul în care acestea sunt conectate, numărul de carteluri inițiale K și cele K orașe în care se află cartelurile, să se determine numărul de moduri în care ţara poate fi împărţită între cartelurile de cafea, modulo 666013.

Date de intrare[edit | edit source]

Fișierul de intrare karbin.txt conține pe prima linie două numere naturale N şi K, reprezentând numărul de oraşe, respectiv numărul cartelurilor existente iniţial. Pe a doua linie din fişier se vor afla K numere, reprezentând oraşele în care se află cele K carteluri. Pe următoarele N-1 linii se vor afla câte două numere naturale, reprezentând o legătură între cele două oraşe.

Date de ieșire[edit | edit source]

Fișierul de ieșire karbout.txt va conține pe prima linie un singur număr natural reprezentând numărul de moduri modulo 666013.

Restricții și precizări[edit | edit source]

  • 1 ⩽ K ⩽ N ⩽ 100 000
  • Pentru teste în valoare de 10% din punctaj se garantează că k ⩽ n ⩽ 7, iar pentru alte 20% din teste se garantează că k = 2.
  • Două oraşe sunt vecine dacă există o stradă bidirecțională între ele.

Exemplu 1[edit | edit source]

karbin.txt
6 3
3 4 5
1 2
1 3
2 4
2 5
4 6
karbout.txt
5


Exemplu 2[edit | edit source]

karbin.txt
0 0
karbout.txt
Nu au fost respectate cerintele


Rezolvare[edit | edit source]

<syntaxhighlight lang="python" line>

  1. 1116 - Karb

import sys

mod = 666013 maxdim = 200005

def check_restrictions(n, k):

   if not (1 <= k <= n <= 100000):
       with open("karbout.txt", "w") as output_file:
           output_file.write("Datele nu corespund restrictiilor impuse\n")
       sys.exit()

def dfs(nod):

   global D, T, special, viz, G
   viz[nod] = 1
   sons = 0
   for fiu in G[nod]:
       if viz[fiu]:
           continue
       sons += 1
       T[fiu] = nod
       dfs(fiu)
   if not sons:
       if special[nod]:
           D[nod][0], D[nod][1] = 0, 1
       else:
           D[nod][0], D[nod][1] = 1, 0
       return
   localD = [[0] * (sons + 1) for _ in range(2)]
   localD[0][0] = 1
   ind = 0
   for fiu in G[nod]:
       if T[fiu] != nod:
           continue
       ind += 1
       localD[0][ind] = (localD[0][ind - 1] * (D[fiu][0] + D[fiu][1])) % mod
       localD[1][ind] = (localD[0][ind - 1] * D[fiu][1] + localD[1][ind - 1] * (D[fiu][0] + D[fiu][1])) % mod
   if not special[nod]:
       D[nod][0], D[nod][1] = localD[0][ind], localD[1][ind]
   else:
       D[nod][0], D[nod][1] = 0, localD[0][ind]

def main():

   global D, T, special, viz, G
   input_file = open("karbin.txt", "r")
   output_file = open("karbout.txt", "w")
   # Citeste N si K
   N, K = map(int, input_file.readline().split())
   
   check_restrictions(N, K)
   special = [0] * maxdim
   viz = [0] * maxdim
   T = [0] * maxdim
   D = [[0] * 2 for _ in range(maxdim)]
   G = [[] for _ in range(maxdim)]
   # Citeste orașele cu carteluri
   cartel_cities = list(map(int, input_file.readline().split()))
   assert len(cartel_cities) == K
   for x in cartel_cities:
       assert not special[x]
       assert 1 <= x <= N
       special[x] = x
   # Citeste legăturile între orașe
   for _ in range(N - 1):
       x, y = map(int, input_file.readline().split())
       assert 1 <= x <= N
       assert 1 <= y <= N
       assert x != y
       G[x].append(y)
       G[y].append(x)
   dfs(1)
   print(D[1][1], file=output_file)
   input_file.close()
   output_file.close()

if __name__ == "__main__":

   main()

</syntaxhighlight>