LOJ6002 「网络流 24 题
来源:互联网 发布:化工公司工艺软件 编辑:程序博客网 时间:2024/06/01 07:34
大家都很强, 可与之共勉。
题意:
给定有向图
题解:
转化为二分图坠大匹配的问题,把每个点
求出它的坠大匹配,用总点数减去就得到了最小路径覆盖。
证明:
我们认为一开始每个点都是独立的为一条路径,总共有
n 条不相交路径。我们每次在二分图里找一条匹配边就相当于把两条路径合成了一条路径,也就相当于路径数减少了1 。所以找到了几条匹配边,路径数就减少了多少。所以有最小路径覆盖=原图的结点数-新图的最大匹配数。
输出方案的话,直接在里面找流量为详见代码
# include <bits/stdc++.h># define N 2010class Network {private : struct edge { int to, w, nxt ; edge ( ) { } edge ( int to, int w, int nxt ) : to ( to ), w ( w ), nxt ( nxt ) { } } g [60010 << 1] ; int head [N], cur [N], ecnt ; int S, T , dep [N] ; inline int dfs ( int u, int a ) { if ( u == T || ! a ) return a ; int flow = 0, v, f ; for ( int& i = cur [u] ; i ; i = g [i].nxt ) { v = g [i].to ; if ( dep [v] == dep [u] + 1 ) { f = dfs ( v, std :: min ( g [i].w, a - flow ) ) ; g [i].w -= f, g [i ^ 1].w += f ; flow += f ; if ( a == flow ) return a ; } } if ( ! flow ) dep [u] = -1 ; return flow ; } inline bool bfs ( int S, int T ) { static std :: queue < int > q ; memset ( dep, 0, sizeof ( int ) * ( T + 1 ) ) ; dep [S] = 1 ; q.push ( S ) ; while ( ! q.empty ( ) ) { int u = q.front ( ) ; q.pop ( ) ; for ( int i = head [u] ; i ; i = g [i].nxt ) { int& v = g [i].to ; if ( g [i].w && ! dep [v] ) { dep [v] = dep [u] + 1 ; q.push ( v ) ; } } } return dep [T] ; }public : Network ( ) { ecnt = 1 ; } inline void add_edge ( int u, int v, int w ) { g [++ ecnt] = edge ( v, w, head [u] ) ; head [u] = ecnt ; g [++ ecnt] = edge ( u, 0, head [v] ) ; head [v] = ecnt ; } inline int dinic ( int S, int T ) { this -> S = S, this -> T = T ; int rt = 0 ; while ( bfs ( S, T ) ) { memcpy ( cur, head, sizeof ( int ) * ( T + 1 ) ) ; rt += dfs ( S, 0x3f3f3f3f ) ; } return rt ; } void display ( int n, int S, int T ) { int ans = n - dinic ( S, T ) ; static std :: bitset < N > vis ; vis.reset ( ) ; for ( int i = 1 ; i <= n ; ++ i ) if ( ! vis.test ( i ) ) { int curr = i ; for ( bool found = 0 ; ; found = 0 ) { printf ( "%d ", curr ) ; vis.set ( curr ) ; for ( int i = head [curr] ; i ; i = g [i].nxt ) { int& v = g [i].to ; if ( g [i].w == 0 && v > n && v <= 2 * n ) { curr = v - n ; found = 1 ; break ; } } if ( found == 0 ) { puts ( "" ) ; break ; } } } printf ( "%d\n", ans ) ; }} Lazer ;int main ( ) { int n, m ; scanf ( "%d%d", & n, & m ) ; const int S = n * 2 + 1, T = n * 2 + 2 ; for ( int i = 1 ; i <= n ; ++ i ) { Lazer.add_edge ( S, i, 1 ) ; Lazer.add_edge ( i + n, T, 1 ) ; } while ( m -- ) { static int u, v ; scanf ( "%d%d", & u, & v ) ; Lazer.add_edge ( u, v + n, 1 ) ; } Lazer.display ( n, S, T ) ; return 0 ;}
阅读全文
0 0
- LOJ6002 「网络流 24 题
- loj6002网络流 24 题 最小路径覆盖 最大流
- loj6002「网络流 24 题」最小路径覆盖(最小路径覆盖+二分图最大匹配)
- 【网络流】网络流24题
- [网络流]: 网络流24题
- 网络流24题
- 网络流24题
- 网络流24题
- 网络流24题
- 「网络流 24 题」试题库
- 「网络流 24 题」试题库
- LOJ6000 「网络流 24 题
- LOJ6001 「网络流 24 题
- LOJ6003 「网络流 24 题
- LOJ6004 「网络流 24 题
- LOJ6005 「网络流 24 题
- LOJ6006「网络流 24 题
- LOJ6007 「网络流 24 题
- jQuery AJAX
- Python学习笔记----装饰器
- Java中的正则表达式
- Java服务端推送和web端推送——GoEasy免费推送服务
- threadlocal原理及常用应用场景2
- LOJ6002 「网络流 24 题
- react踩坑不完全指北(1)
- Python,列表
- 递归再理解
- sublime text3安装以及插件配置教程
- Java设计模式透析之 —— 模板方法(Template Method)
- layout_below与layout_alignBottom的区别
- poi工具类
- RigidBody的基础知识