[Cogs728] [网络流24题#3] 最小路径覆盖 [网络流,最大流,二分图匹配]
建图:源点—>边的起点(集合1中的)—>边的终点(集合2中的)—>汇点,所有边权均为1,
计算最大流,最后枚举起点的出边,边权为0的即为匹配上的,
可以这样理解:每条边表示起点和终点形成一组可选匹配,所以每个点只能被匹配1次(做起点和终点分别1次),所以可以看成是二分图匹配。
代码略丑:
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cstdlib> 5 #include <cmath> 6 #include <ctime> 7 #include <algorithm> 8 #include <queue> 9 10 using namespace std; 11 12 template<const int _n> 13 struct Edge 14 { 15 struct Edge_base { int to,next,w; }e[_n]; 16 int cnt,p[_n]; 17 Edge() { clear(); } 18 int start(const int x) { return p[x]; } 19 void insert(const int x,const int y,const int z) 20 { e[++cnt].to=y; e[cnt].next=p[x]; e[cnt].w=z; p[x]=cnt; return ; } 21 Edge_base& operator[](const int x) { return e[x]; } 22 void clear() { cnt=1,memset(p,0,sizeof(p)); } 23 }; 24 25 int n,m,SSS,TTT,Ans; 26 int level[310],cur[310],Out[310],to[310],from[310]; 27 bool visited[310]; 28 Edge<15000> e; 29 30 bool Bfs(const int S) 31 { 32 int i,t; 33 queue<int> Q; 34 memset(level,0,sizeof(level)); 35 level[S]=1; 36 Q.push(S); 37 while(!Q.empty()) 38 { 39 t=Q.front();Q.pop(); 40 for(i=e.start(t);i;i=e[i].next) 41 { 42 if(!level[e[i].to] && e[i].w) 43 { 44 level[e[i].to]=level[t]+1; 45 Q.push(e[i].to); 46 } 47 } 48 } 49 return level[TTT]; 50 } 51 52 int Dfs(const int S,const int bk) 53 { 54 if(S==TTT)return bk; 55 int rest=bk; 56 for(int &i=cur[S];i;i=e[i].next) 57 { 58 if(level[e[i].to]==level[S]+1 && e[i].w) 59 { 60 int flow=Dfs(e[i].to,min(e[i].w,rest)); 61 e[i].w-=flow; 62 e[i^1].w+=flow; 63 if((rest-=flow)<=0)break; 64 } 65 } 66 if(bk==rest)level[S]=0; 67 return bk-rest; 68 } 69 70 int Dinic() 71 { 72 int flow=0; 73 while(Bfs(SSS)) 74 { 75 memcpy(cur,e.p,sizeof(int)*(n+n+3)); 76 flow+=Dfs(SSS,0x3f3f3f3f); 77 } 78 return flow; 79 } 80 81 82 83 int main() 84 { 85 freopen("path3.in","r",stdin); 86 freopen("path3.out","w",stdout); 87 int i,j,x,y; 88 89 scanf("%d%d",&n,&m); 90 for(i=1;i<=m;++i) 91 { 92 scanf("%d%d",&x,&y); 93 e.insert(x,y+n,1); 94 e.insert(y+n,x,0); 95 Out[x]++; 96 } 97 98 SSS=n+n+1,TTT=n+n+2; 99 for(i=1;i<=n;++i) 100 { 101 e.insert(SSS,i,1); 102 e.insert(i,SSS,0); 103 e.insert(i+n,TTT,1); 104 e.insert(TTT,i+n,0); 105 } 106 107 Dinic(); 108 109 for(i=e.start(SSS);i;i=e[i].next) 110 { 111 if(e[i].w)continue; 112 for(j=e.start(e[i].to);j;j=e[j].next) 113 { 114 if(e[j].to!=SSS && !e[j].w) 115 { 116 to[e[i].to]=e[j].to-n; 117 from[e[j].to-n]=e[i].to; 118 break; 119 } 120 } 121 } 122 123 for(i=1;i<=n;++i) 124 { 125 if(!from[i]) 126 { 127 int t=i; 128 while(t) 129 { 130 printf("%d ",t); 131 t=to[t]; 132 } 133 printf("\n"); 134 Ans++; 135 } 136 } 137 138 printf("%d\n",Ans); 139 140 return 0; 141 }
View Code
匈牙利写法详见:http://www.cnblogs.com/Ngshily/p/4988909.html
转载于:https://www.cnblogs.com/Gster/p/4989326.html
[Cogs728] [网络流24题#3] 最小路径覆盖 [网络流,最大流,二分图匹配]相关推荐
- 【网络流24题】最小路径覆盖问题
[题目]1738: 最小路径覆盖问题 [题解]网络流 关于输出路径,因为即使有反向弧经过左侧点也一定会改变左侧点的去向,若没连向右侧就会被更新到0,所以不用在意. mark记录有入度的右侧点,然后从没 ...
- 流网络的最小割问题c语言,「网络流24题」最小路径覆盖问题
Description 问题描述: 给定有向图G=(V,E).设P 是G 的一个简单路(顶点不相交)的集合.如果V 中每个顶点恰好在P 的一条路上,则称P是G 的一个路径覆盖.P 中路径可以从V 的任 ...
- LibreOJ #6002. 「网络流 24 题」最小路径覆盖
内存限制:256 MiB 时间限制:1000 ms 标准输入输出 题目类型:传统 评测方式:Special Judge 上传者: 匿名 网络流 最大流 屠龙宝刀点击就送 #include <cs ...
- LOJ#6002. 「网络流 24 题」最小路径覆盖
模板. 1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 //#include<ti ...
- 洛谷 - P2764 最小路径覆盖问题(最大流+二分图最小路径覆盖+路径打印)
题目链接:点击查看 题目大意:给出一个由n个点和m条边组成的有向无环图,现在需要我们求最少可以将n个点分为多少条简单路径,并打印出每一条路径 题目分析:题意挺难懂的..简单来说就是让求二分图最小路径覆 ...
- 【网络流24题】魔术球问题(最大流)
[网络流24题]魔术球问题(最大流) 题面 Cogs 题解 是不是像极了最小路径覆盖? 因此,我们枚举放到哪一个球(也可以二分) 然后类似于最小路径覆盖的连边 因为一根柱子对应一个路径的覆盖 所以,提 ...
- 【网络流24题】星际转移问题(最大流)
[网络流24题]星际转移问题(最大流) 题面 Cogs 题解 因为天数是未知的,所以我们要想办法处理天数 可以选择二分或者依次累加天数 因为数据范围较小,使用二分可能反而复杂度会增高 所以使用不断累加 ...
- [网络流24题][CODEVS1922]骑士共存问题(最大流)
问题描述 传送门 题解 首先介绍ATP神犇的做法: 和方格取数3几乎一样,黑白染色,可以发现能攻击到的点颜色不同. 那么从超级源向每一个黑点连边,容量为1,从每一个白点向超级汇连边,容量为1:从黑点向 ...
- 线性规划与网络流24题 运输问题(最裸的费用流了)
存费用流模板 用sfpa算出最小费用和路径,沿这条路径增广 1 const 2 inf=maxlongint; 3 var 4 n,m:longint; 5 map,a,w:array[0..120, ...
- [网络流24题][CODEVS1237]餐巾计划问题(费用流)
题目描述 传送门 题解 拆点,把每天的点拆成xi和yi,xi表示每一天的脏毛巾,yi表示每一天的新毛巾. 从超级源向xi连边,容量为ri,费用为0: 从yi向超级汇连边,容量为ri,费用为0: 从超级 ...
最新文章
- Python怎么利用多核cpu
- 无法添加选择的Web部件
- HBuilder设置代码自动换行的方法
- SAP Spartacus 如何使用 API 从浏览器 local Storage 读取数据
- 科学计算机eq7,科学计算器HiEdu 580 Scientific Calculator
- python实现搜索之二分查找
- 23、jQuery九类选择器/jQuery常用Method-API/jQuery常用Event-API
- zabbix3.0.4 邮件告警详细配置
- 2019.7.19刷题统计
- 电脑计算机无法安3.5,win10 net framework 3.5安装不了的完美解决办法
- java sao_JavaScript 的一些SAO操作
- 车辆vin信息(含发动机号)
- 智慧时代正向我们走来(一)
- matlab solve和subs,【MATLAB】matlab中的subs()函数和solve()函数用法
- VMware中建立共享文件夹 win7
- 如何优雅地删除Redis大键
- 糯米网电子商务模式:上线当天销售额600多万元的缘由
- 【OJ每日一练】1029 - 字母密码
- 乐乐音乐4.0简洁版
- 手把手教你使用R语言做出SCI论文中的表二(单因素分析表)(2)