Skip to content

Graph Theory #3

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions graph-theory/clique/solution.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# See https://en.wikipedia.org/wiki/Tur%C3%A1n_graph for the formulae we used here.
# We first use the approximation (as given in the challege hint) to get started,
# then we increment the result until the exact condition is met.

import math


def exact(n, k):
return (
n * n - (n % k) * math.ceil(n / k) ** 2 - (k - n % k) * math.floor(n / k) ** 2
) / 2


for case in range(int(input())):
N, M = map(int, input().split())
k = math.ceil(N * N / (N * N - 2 * M))
while M > exact(N, k):
k += 1
print(k)
74 changes: 74 additions & 0 deletions graph-theory/jeanies-route/solution.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# Welp. I had tried my best, but this challenge needs so many steps
# and thus is quite verbose to write. I will try to make myself clear.
#
# First we notice that the edges used are always the same no matter
# where we start or finish. These paths form a subtree of the original
# graph (which is the smallest subtree containing all the delivery cities).
#
# When we start and finish at the same city, the total distance is always
# twice of the sum of all paths in the said subtree. And when we start
# and finish in different cities, the distance should subtract the path
# between these two cities. Thus we must maximize the distance between
# the starting city and the finishing city.
#
# Using Dfs will greatly simplify the code. But the N seems too huge to
# do the recursion properly. Maybe next time.
#
# So here's what to do:
# 1. Find the said subtree
# 2. Find the longest path in it
# 3. Do the subtraction
#
# Time complexity: O(N)

from collections import deque

N, K = map(int, input().split())
paths = [[] for i in range(N)]
delivery = set(map(lambda x: int(x) - 1, input().split()))
for i in range(N - 1):
frm, to, d = map(int, input().split())
paths[frm - 1].append((to - 1, d))
paths[to - 1].append((frm - 1, d))
# pick one delivery city as the root and construct a tree
parent = [-1] * N
root = next(iter(delivery))
q = deque([root])
while q:
x = q.popleft()
for path in paths[x]:
if path[0] != parent[x]:
q.append(path[0])
parent[path[0]] = x
# find unused cities and discard them, getting the subtree
keep = [False] * N
for i in delivery:
x = i
while x != -1 and not keep[x]:
keep[x] = True
x = parent[x]
paths = [[path for path in paths[i] if keep[path[0]] and keep[i]] for i in range(N)]


# now we find the longest path in the tree
def furthest_vertex(
start,
): # return a tuple contains the vertex index and the path length
result = (start, 0)
visited = [False] * N
q = deque([result])
while q: # run a Bfs from 'start' and count the path length from it
x = q.popleft()
if x[1] > result[1]: # keep track of the furthest vertex
result = x
visited[x[0]] = True
for path in paths[x[0]]:
if not visited[path[0]]:
q.append((path[0], x[1] + path[1]))
return result


start = next(i for i, x in enumerate(paths) if len(x)) # get the first city in list
longest_path = furthest_vertex(furthest_vertex(start)[0])[1]
# all paths exist in both connected cities, so no need to multiply by 2 here
print(sum(sum(x[1] for x in l) for l in paths) - longest_path)