Recursos-LCC

Um arquivo de todo material que consegui reunir, pertinente ao curso de LCC da UM.

View on GitHub

LA2 | Treino 2 | Cidade


'''
Podemos usar um (multi) grafo para representar um mapa de uma cidade: 
cada nó representa um cruzamento e cada aresta uma rua.
Pretende-se que implemente uma função que calcula o tamanho de uma cidade, 
sendo esse tamanho a distância entre os seus cruzamentos mais afastados.
A entrada consistirá numa lista de nomes de ruas (podendo assumir que os 
nomes de ruas são únicos). Os identificadores dos cruzamentos correspondem a 
letras do alfabeto, e cada rua começa (e acaba) no cruzamento 
identificado pelo primeiro (e último) caracter do respectivo nome.
'''

def build(ruas):
    adj = {}

    for rua in ruas:
        c1 = rua[0]
        c2 = rua[-1]
        if c1 not in adj:
            adj[c1] = {}
        if c2 not in adj:
            adj[c2] = {}
        if c2 in adj[c1] and adj[c1][c2] < len(rua):
            continue
        adj[c1][c2] = len(rua)
        adj[c2][c1] = len(rua)

    return adj


####################################
#        Solved with dijkstra      #
####################################


def dijkstra(adj,o):
    pai = {}
    dist = {}
    dist[o] = 0
    orla = {o}
    while orla:
        v = min(orla,key=lambda x:dist[x])
        orla.remove(v)
        for d in adj[v]:
            if d not in dist:
                orla.add(d)
                dist[d] = float("inf")
            if dist[v] + adj[v][d] < dist[d]:
                pai[d] = v
                dist[d] = dist[v] + adj[v][d]
    return pai

def tamanho(ruas):
    adj = build(ruas)
    dist = 0
    for cruz in adj.keys():
        pai = dijkstra(adj, cruz)
        for cruzd in adj.keys():
            if cruz != cruzd:
                temp = 0
                d = cruzd
                while d in pai:
                    temp += adj[d][pai[d]]
                    d = pai[d]
                dist = max(dist, temp)

    return dist


#########################################
#        Solved with Floy-Warshall      #
#########################################


def fw(adj):
    dist = {}
    for o in adj:
        dist[o] = {}
        for d in adj:
            if o == d:
                dist[o][d] = 0
            elif d in adj[o]:
                dist[o][d] = adj[o][d]
            else:
                dist[o][d] = float("inf")
    for k in adj:
        for o in adj:
            for d in adj:
                if dist[o][k] + dist[k][d] < dist[o][d]:
                    dist[o][d] = dist[o][k] + dist[k][d]
    return dist 


def tamanho(ruas):
    adj = build(ruas)
    dist = fw(adj)
    final = 0
    for i in adj:
        for k in adj:
            final = max(final, dist[i][k])
    return final


Testes

# 1
ruas = ["raio","central","liberdade","chaos","saovictor","saovicente","saodomingos","souto","capelistas","anjo","taxa"]
> Resultado = 25

# 2
ruas = ["ab","bc","bd","cd"]
> Resultado = 4

retroceder