1118 - Clepsidra

De la Universitas MediaWiki
Versiunea pentru tipărire nu mai este suportată și poate avea erori de randare. Vă rugăm să vă actualizați bookmarkurile browserului și să folosiți funcția implicită de tipărire a browserului.

Un graf conex cu N noduri și M muchii poate fi privit ca o clepsidră cu centrul în nodul X, 1 ≤ X ≤ N, dacă putem împărți toate nodurile, mai puțin nodul X, în două submulțimi nevide astfel încât orice drum de la un nod dintr-o mulțime la un nod din cealaltă mulțime trece prin nodul X. Voi trebuie să determinați numărul de moduri distincte în care putem privi graful ca o clepsidră pentru fiecare din cele N noduri alese drept centru, modulo 666013. Două moduri se consideră distincte dacă cele două submulțimi aferente sunt diferite. Ordinea submulțimilor într-un mod este relevantă, dar ordinea nodurilor în cadrul unei mulțimi nu este. Spre exemplu, soluțiile ({1,2,3}, {4,5}) şi ({4,5}, {1,2,3}) sunt distincte, dar soluţiile ({4,5}, {1,2,3}) şi ({4,5}, {1,3,2}) nu sunt distincte.

Date de intrare

Fișierul de intrare clepsidra.in conține pe prima linie două numere naturale, N și M, reprezentând numărul de noduri, respectiv numărul de muchii din graf. Pe următoarele M linii se vor afla câte două numere naturale separate prin câte un spaţiu, reprezentând câte o muchie.

Date de ieșire

Fișierul de ieșire clepsidra.out va conține N linii. A i-a linie, 1 ≤ i ≤ N, va conține numărul de moduri în care putem privi graful ca o clepsidră cu centrul în nodul i, modulo 666013.În cazul în care restricțiile nu sunt îndeplinite, se va afișa mesajul "Datele nu corespund restrictiilor impuse".

Restricții și precizări

  • 2 ≤ N ≤ 200 002
  • 1 ≤ M ≤ 250 002
  • Pentru 40% din teste avem restricţiile 2 ≤ N ≤ 1002 și 1 ≤ M ≤ 1502.
  • Atentie! Graful este conex.

Exemplul 1:

clepsidra.in

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

clepsidra.out

0
0
2
0
2
0

Explicație

Pentru nodul cu indicele 3, soluţiile sunt: ({2}, {1,4,5,6}) și ({1,4,5,6}, {2})

Pentru nodul cu indicele 5, soluţiile sunt: ({6}, {1,2,3,4}) și ({1,2,3,4},{6})

Exemplul 2:

clepsidra.in

200200 213
4 3
1 3
5 4
4 1
3 2
1 5
5 6

clepsidra.out

Datele nu corespund restrictiilor impuse

Rezolvare

MOD = 666013

def power(x, y):
    rez = 1
    while y > 0:
        if y % 2 == 1:
            rez = (rez * x) % MOD
        x = (x * x) % MOD
        y = y // 2
    return rez % MOD

def check_constraints(n, m):
    if 2 <= n <= 200002 and 1 <= m <= 250002:
        return True
    else:
        with open("clepsidraOUT.txt", 'w') as out:
            out.write("Datele nu corespund restrictiilor impuse\n")
        return False

def dfs(nc):
    global niv, nmin, nrfii, tati, viz, a, r

    viz[nc] = 1
    niv[nc] = niv[tati[nc]] + 1
    nmin[nc] = niv[nc]
    for nv in a[nc]:
        if viz[nv] == 0:
            tati[nv] = nc
            dfs(nv)
            nmin[nc] = min(nmin[nc], nmin[nv])
            if nc != r and nmin[nv] >= niv[nc]:
                nrfii[nc] += 1

        elif tati[nc] != nv:
            nmin[nc] = min(nmin[nc], niv[nv])

def main():
    global niv, nmin, nrfii, tati, viz, a, r

    with open("clepsidraIN.txt", 'r') as f:
        n, m = map(int, f.readline().split())
        
        if not check_constraints(n, m):
            return
        
        a = [[] for _ in range(n + 1)]
        for _ in range(m):
            x, y = map(int, f.readline().split())
            a[x].append(y)
            a[y].append(x)

    r = 1
    niv = [0] * (n + 1)
    nmin = [0] * (n + 1)
    nrfii = [0] * (n + 1)
    tati = [0] * (n + 1)
    viz = [0] * (n + 1)

    dfs(r)

    with open("clepsidraOUT.txt", 'w') as out:
        if nrfii[r] > 1:
            out.write(str((power(2, nrfii[r]) + MOD - 2) % MOD) + "\n")
        else:
            out.write("0\n")

        for i in range(2, n + 1):
            if nrfii[i] == 0:
                out.write("0\n")
            else:
                out.write(str((power(2, nrfii[i] + 1) + MOD - 2) % MOD) + "\n")

if __name__ == "__main__":
    main()