赞 | 7 |
VIP | 0 |
好人卡 | 1 |
积分 | 18 |
经验 | 34644 |
最后登录 | 2024-11-18 |
在线时间 | 951 小时 |
Lv3.寻梦者
- 梦石
- 0
- 星屑
- 1789
- 在线时间
- 951 小时
- 注册时间
- 2012-7-5
- 帖子
- 245
|
加入我们,或者,欢迎回来。
您需要 登录 才可以下载或查看,没有帐号?注册会员
x
本帖最后由 浮云半仙 于 2016-11-17 00:21 编辑
其实我是来卖萌的(
见到最短路算法都在这里大放异彩,忍不住想来一发网络流
网络流是个什么问题呢,大概可以这样想象下:假设自来水公司的水有+oo之多并且水足够,现在水流经网络般复杂的自来水管,到达目的地,每秒钟能运送多少水量呢?(
在游戏里面我倒是更倾向用网络流做二分图匹配的应用,例如:
班上有n个同学,每个人都有一些希望能坐同桌的人,但是最终每个人只能选一个人坐同桌。现在老师知道每位同学都希望和哪些同学做同桌,那么老师最多能够满足多少位同学的心愿呢?
建立二分图,跑下最大流√ok。为什么请自行查询相关定理与资料。
再例如最小路径覆盖:给一个有向无环图图,求最少能使用多少条路径,不重不漏地覆盖整张图上所有的点? 这里有讲解
最大流不过瘾还有最小费用最大流,还有带流量上下界的最大流.....
感觉会很有意思的。我就是来开脑洞的(逃
最大流实现代码:代码好像在这里显示有些问题,请点这里下载原文件:
dinic.zip
(884 Bytes, 下载次数: 82)
#注意,运行过一次最大流之后会毁掉图的 class Dinic class Edge attr_accessor :from, :to, :rem def initialize(a, b, c) @from = a @to = b @rem = c end end attr_accessor :source, :sink attr_reader :graph, :edges def initialize(vs, sr, sk) #顶点数,起点,终点 [url=home.php?mod=space&uid=171370]@source[/url] = sr @sink = sk @graph = Array.new(vs+1) {Array.new} @edges = [] #private @dist = Array.new(vs+1, 0) @vis = Array.new(vs+1, false) @q = Array.new(vs+1, nil) end def addedge(u, v, c) @edges.push(Edge.new(u, v, c)) @edges.push(Edge.new(v, u, 0)) @graph[u].push(@edges.size-2) @graph[v].push(@edges.size-1) end def bfs @vis.fill(false) @dist[@source] = 0 head = 0 tail = 1 @q[head] = @source @vis[@source] = true while head < tail u = @q[tail-1] head += 1 @graph[u].each do |i| e = @edges[i] if !@vis[e.to] && e.rem > 0 @vis[e.to] = true @dist[e.to] = @dist[u]+1 @q[tail] = e.to tail += 1 end end end return @vis[@sink] end def dfs(u, flow) return flow if u == @sink || flow == 0 n = 0 r = 0 @graph[u].each do |i| e = @edges[i] if @dist[e.to] == @dist[u]+1 n = dfs(e.to, [flow, e.rem].min) next if n <= 0 r += n e.rem -= n flow -= n @edges[i^1].rem += n break if flow == 0 end end return r end def maxflow() r = 0 r += dfs(@source, 0x7fffffff) while bfs r end end #test,正确答案为50 d = Dinic.new(4, 1, 4) d.addedge(1, 2, 40) d.addedge(1, 4, 20) d.addedge(2, 4, 20) d.addedge(2, 3, 30) d.addedge(3, 4, 10) puts d.maxflow # => 50
#注意,运行过一次最大流之后会毁掉图的
class Dinic
class Edge
attr_accessor :from, :to, :rem
def initialize(a, b, c)
@from = a
@to = b
@rem = c
end
end
attr_accessor :source, :sink
attr_reader :graph, :edges
def initialize(vs, sr, sk) #顶点数,起点,终点
[url=home.php?mod=space&uid=171370]@source[/url] = sr
@sink = sk
@graph = Array.new(vs+1) {Array.new}
@edges = []
#private
@dist = Array.new(vs+1, 0)
@vis = Array.new(vs+1, false)
@q = Array.new(vs+1, nil)
end
def addedge(u, v, c)
@edges.push(Edge.new(u, v, c))
@edges.push(Edge.new(v, u, 0))
@graph[u].push(@edges.size-2)
@graph[v].push(@edges.size-1)
end
def bfs
@vis.fill(false)
@dist[@source] = 0
head = 0
tail = 1
@q[head] = @source
@vis[@source] = true
while head < tail
u = @q[tail-1]
head += 1
@graph[u].each do |i|
e = @edges[i]
if !@vis[e.to] && e.rem > 0
@vis[e.to] = true
@dist[e.to] = @dist[u]+1
@q[tail] = e.to
tail += 1
end
end
end
return @vis[@sink]
end
def dfs(u, flow)
return flow if u == @sink || flow == 0
n = 0
r = 0
@graph[u].each do |i|
e = @edges[i]
if @dist[e.to] == @dist[u]+1
n = dfs(e.to, [flow, e.rem].min)
next if n <= 0
r += n
e.rem -= n
flow -= n
@edges[i^1].rem += n
break if flow == 0
end
end
return r
end
def maxflow()
r = 0
r += dfs(@source, 0x7fffffff) while bfs
r
end
end
#test,正确答案为50
d = Dinic.new(4, 1, 4)
d.addedge(1, 2, 40)
d.addedge(1, 4, 20)
d.addedge(2, 4, 20)
d.addedge(2, 3, 30)
d.addedge(3, 4, 10)
puts d.maxflow # => 50
|
评分
-
查看全部评分
|