Skip to content

Instantly share code, notes, and snippets.

@knuu
Created October 16, 2016 17:44
Show Gist options
  • Save knuu/6dbc267a487fd15109e710abb9ed16f8 to your computer and use it in GitHub Desktop.
Save knuu/6dbc267a487fd15109e710abb9ed16f8 to your computer and use it in GitHub Desktop.
AOJ2594 Reverse Roads
import collections
class MaxFlow:
"""Dinic Algorithm: find max-flow
complexity: O(EV^2)
used in GRL6A(AOJ)
"""
class Edge:
def __init__(self, to, cap, rev):
self.to, self.cap, self.rev = to, cap, rev
def __init__(self, V):
""" V: the number of vertexes
E: adjacency list
source: start point
sink: goal point
"""
self.V = V
self.E = [[] for _ in range(V)]
def add_edge(self, fr, to, cap):
self.E[fr].append(self.Edge(to, cap, len(self.E[to])))
self.E[to].append(self.Edge(fr, 0, len(self.E[fr])-1))
def dinic(self, source, sink, INF=10**9):
"""find max-flow"""
maxflow = 0
while True:
self.bfs(source)
if self.level[sink] < 0:
return maxflow
self.itr = [0] * self.V
while True:
flow = self.dfs(source, sink, INF)
if flow > 0:
maxflow += flow
else:
break
def dfs(self, vertex, sink, flow):
"""find augmenting path"""
if vertex == sink:
return flow
for i in range(self.itr[vertex], len(self.E[vertex])):
self.itr[vertex] = i
e = self.E[vertex][i]
if e.cap > 0 and self.level[vertex] < self.level[e.to]:
d = self.dfs(e.to, sink, min(flow, e.cap))
if d > 0:
e.cap -= d
self.E[e.to][e.rev].cap += d
return d
return 0
def bfs(self, start):
"""find shortest path from start"""
que = collections.deque()
self.level = [-1] * self.V
que.append(start)
self.level[start] = 0
while que:
fr = que.popleft()
for e in self.E[fr]:
if e.cap > 0 and self.level[e.to] < 0:
self.level[e.to] = self.level[fr] + 1
que.append(e.to)
N, M = map(int, input().split())
mf = MaxFlow(N)
rev_edge = []
for i in range(M):
s, t = [int(x)-1 for x in input().split()]
mf.add_edge(s, t, 1)
mf.add_edge(t, s, 1)
rev_edge.append((i+1, t, len(mf.E[t])-1))
source, sink = [int(x)-1 for x in input().split()]
print(mf.dinic(source, sink))
ans = []
for i, t, idx in rev_edge:
e = mf.E[t][idx]
if mf.E[e.to][e.rev].cap == 1:
ans.append(i)
print(len(ans))
if ans:
print(*ans, sep='\n')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment