jon666 @ 2019-11-11 02:32:22
我把当前边优化写成这样感觉也没错啊,建V次层次图,DFS最坏每到达V个边(增广路),删掉1个边,一共E个边,那最坏就是O(V^2E)哪里错了啊。。。
import sys
sys.setrecursionlimit(100000)
from collections import deque
class NetworkFlow:
def __init__(self,s,t):
self.s = s
self.t = t
self.c = {}
self.f = {}
def add_edge(self,u,v,c):
if None == self.c.get(u):
self.c[u] = {}
self.f[u] = {}
self.c[u][v] = c
self.f[u][v] = 0
def get_cap(self,u,v):
return self.c[u][v] if u in self.c and v in self.c[u] else 0
def get_residual_cap(self,u,v):
if u in self.c and v in self.c[u] and self.c[u][v]>0:
return self.c[u][v] - self.f[u][v]
if v in self.c and u in self.c[v] and self.c[v][u]>0:
return self.f[v][u]
return 0
def make_residual_edges(self):
edges = {}
for u in self.c.keys():
for v in self.c[u].keys():
if u not in edges:
edges[u] = {}
if v not in edges:
edges[v] = {}
edges[u][v] = self.get_residual_cap(u,v)
edges[v][u] = self.get_residual_cap(v,u)
return edges
def make_level_edges(self):
res = self.make_residual_edges()
q = deque([self.s])
vis = {self.s}
level = {}
while len(q)>0:
u = q.popleft()
for v in res[u].keys():
if res[u][v] > 0 and not v in vis:
if u not in level:
level[u] = set()
level[u].add(v)
vis.add(v)
q.append(v)
return level
def dfs_level(self,level,u,path):
path.append(u)
if u == self.t:
return True
if u in level:
for v in list(level[u]):
if self.dfs_level(level,v,path):
return True
else:
level[u].remove(v)
path.pop()
return False
def update_flow_level(self,path,level):
pf = float('inf')
for i in range(len(path)-1):
u,v = path[i],path[i+1]
pf = min( pf, self.get_residual_cap(u,v) )
for i in range(len(path)-1):
u,v = path[i],path[i+1]
if self.get_cap(u,v) > 0:
self.f[u][v] += pf
else:
self.f[v][u] -= pf
if self.get_residual_cap(u,v) <= 0:
level[u].remove(v)
def dinic(self):
while True:
counter = 0
level = self.make_level_edges()
while True:
path = []
if self.dfs_level(level,self.s,path):
counter +=1
self.update_flow_level(path,level)
else:
break
if counter == 0:
break
def max_flow_value(self):
u = self.s
val = 0
for v in self.c[u].keys():
val += self.f[u][v]
return val
data = []
counter = 0
while True:
counter += 1
try:
line = input().strip().split(' ')
line = [int(i) for i in line]
if counter == 1:
s,t = line[2],line[3]
else:
data.append((line[0],line[1],line[2]))
except EOFError:
break
network = NetworkFlow(s,t)
cache = {}
for u,v,c in data:
if u==t:
continue
if v==s:
continue
if u==v:
continue
if None == cache.get(u):
cache[u] = {}
if cache.get(v) and cache[v].get(u):
if cache[v][u] > c:
cache[v][u] -= c
elif cache[v][u] == c:
cache[v].pop(u)
else:
x = cache[v].pop(u)
cache[u][v] = c - x
elif cache.get(u) and cache[u].get(v):
cache[u][v] += c
else:
cache[u][v] = c
for u in cache.keys():
for v in cache[u].keys():
network.add_edge(u,v,cache[u][v])
network.dinic()
val = network.max_flow_value()
print(str(val))
by jon666 @ 2019-11-11 02:36:41
其实我更想知道我这样写能不能保住EV^2时间复杂度...
by 陈诺sb @ 2019-11-11 02:37:38
%%%
by 陈诺sb @ 2019-11-11 02:37:50
让我 看看那 @jon666
by 陈诺sb @ 2019-11-11 02:38:00
你还 没睡么 @jon666
by fa_555 @ 2019-11-11 07:07:00
py 常数不是本来就大吗(
我写的 dij 交 python 全 TLE,交 pypy TLE 一半(
by 三氯甲硅烷 @ 2019-11-11 07:09:58
用py3 or pypy
by lsy263 @ 2019-11-11 07:18:52
@jon666 py本来就慢...= =
by yummy @ 2019-11-11 07:37:00
洛谷时间限制本来就不是为Python设计的
大概是物以希为贵罢。北京的白菜运往浙江,便用红头绳系住菜根,倒挂在水果店头,尊为“胶菜”;福建野生着的芦荟,一到北京就请进温室,且美其名曰“龙舌兰”。Python也颇受了这样的优待,不但OJ支持Python,几个管理还为Python的时限操心操心。
by microchip @ 2019-11-11 07:42:49
c++的速度是py10倍……
by KokiNiwa @ 2019-11-11 07:51:32
@yummy 真会引用[捂脸.jpg]