-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathFlights.py
145 lines (128 loc) · 5.01 KB
/
Flights.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
# -*- coding: utf-8 -*-
"""
Spyder Editor
This temporary script file is located here:
C:\Users\User Name\.spyder2\.temp.py
"""
# Given a list of cities with certain connections, and
# flights given certain times it takes to get from one
# city to another, what is the time where it gets
# a certain amount of people from the east coast
# to the west coast.
# We take this as a Max Flow Problem in order to work with it
def main():
citynum, ecity, wcity, connum = map(int, raw_input().split())
eastcities = map(int, raw_input().split())
eastcitpop = map(int, raw_input().split())
westcities = map(int, raw_input().split())
# Create an Information List that holds the capacity and hour of a connection
InformationList = [[(0,0) for x in xrange(citynum)] for x in xrange(citynum)]
# Set up an adjacency list, origins, destinations, capacities, and hours
AdjacencyList = [list() for x in xrange(citynum +2)]
origins = [0 for x in xrange(connum)]
destinations = [0 for x in xrange(connum)]
capacities = [0 for x in xrange(connum)]
hours = [0 for x in xrange(connum)]
AdjacencyList[citynum] = eastcities
# Fill up arrays and set up origin and destination
for x in xrange(connum):
origin, destination, capacity, hour = map(int, raw_input().split())
origins[x] = origin
destinations[x] = destination
capacities[x] = capacity
hours[x] = hour
InformationList[origin][destination] = (capacity, hour)
AdjacencyList[origin].append(destination)
check = False
#Set up the first cities
for i in westcities:
AdjacencyList[i].append(citynum + 1)
for val in eastcities:
if (citynum +1) not in startingcheck_dfs(AdjacencyList, val):
check = True
break
# If there is not a way to get to the east cities from the westcities
# return -1.
if (check == True):
print -1
return
# Create a time graph for 25.
for t in range(1, 25):
if (createGraph(t, hours, citynum, connum, eastcities, westcities, capacities, eastcitpop, origins, destinations)):
print (t-1)
break
# Create a graph, creating a new node for every hour that goes by.
def createGraph(t, times, citynum, flights, eastcities, westcities, capacities, eastcitypop, origin, destinations):
graph = [[list() for j in range(t)] for i in range(citynum + 1)]
cap = dict()
superstart = (citynum, 0)
supersink = (citynum, t - 1)
for i in range(flights):
for j in range(t - times[i]):
a = origin[i]
b = destinations[i]
c = times[i]
d = capacities[i]
graph[a][j].append((b, j + c))
graph[b][j+c].append((a, j))
cap[translate(a, j, b, j+c)] = d
cap[translate(b, j + c, a, j)] = 0
for i in range(citynum):
for j in range(t - 1):
graph[i][j].append((i, j+1))
graph[i][j+1].append((i,j))
cap[translate(i, j, i, j + 1)] = 9999
cap[translate(i, j+1, i, j)] = 0
for i in range(len(eastcities)):
graph[citynum][0].append((eastcities[i], 0))
cap[translate(citynum, 0, eastcities[i], 0)] = eastcitypop[i]
for i in range(len(westcities)):
graph[westcities[i]][t-1].append((citynum, t-1))
cap[translate(westcities[i], t-1, citynum, t-1)] = 9999
flow = 0
# Run Fold-Fulkerson
while True:
paths = dfs_paths(graph, cap, superstart, supersink)
if (len(paths)) == 0:
break
c = list();
for i in xrange(0, len(paths) -1):
x = cap[translate(paths[i][0], paths[i][1], paths[i+1][0], paths[i+1][1])]
c.append(x)
minimum = min(c)
flow = flow + minimum
for i in xrange(0, len(paths) -1):
a = paths[i][0]
b = paths[i][1]
c = paths[i+1][0]
d = paths[i+1][1]
cap[translate(a,b,c,d)] -= minimum
if (a != citynum and c != citynum):
cap[translate(c,d,a,b)] += minimum
if (flow == sum(eastcitypop)):
return True
else:
return False
# Hash Table
def translate(a, b, c, d):
return str(a).zfill(3) + str(b).zfill(3) + str(c).zfill(3) + str(d).zfill(3)
# Check if there exists a path
def startingcheck_dfs(g, start, path = []):
path= path+[start]
for node in g[start]:
if not node in path:
path = startingcheck_dfs (g, node, path)
return path
# Create that path.
def dfs_paths(graph, cap, start, goal):
stack = [(start, [start])]
while stack:
(vertex, path) = stack.pop()
for next in graph[vertex[0]][vertex[1]]:
if (next[0], next[1]) not in path and cap[translate(vertex[0], vertex[1], next[0], next[1])] > 0:
if (next == goal):
return path + [next]
else:
stack.append((next, path + [next]))
return []
main()