建图:源点—>边的起点(集合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] 最小路径覆盖 [网络流,最大流,二分图匹配]相关推荐

  1. 【网络流24题】最小路径覆盖问题

    [题目]1738: 最小路径覆盖问题 [题解]网络流 关于输出路径,因为即使有反向弧经过左侧点也一定会改变左侧点的去向,若没连向右侧就会被更新到0,所以不用在意. mark记录有入度的右侧点,然后从没 ...

  2. 流网络的最小割问题c语言,「网络流24题」最小路径覆盖问题

    Description 问题描述: 给定有向图G=(V,E).设P 是G 的一个简单路(顶点不相交)的集合.如果V 中每个顶点恰好在P 的一条路上,则称P是G 的一个路径覆盖.P 中路径可以从V 的任 ...

  3. LibreOJ #6002. 「网络流 24 题」最小路径覆盖

    内存限制:256 MiB 时间限制:1000 ms 标准输入输出 题目类型:传统 评测方式:Special Judge 上传者: 匿名 网络流 最大流 屠龙宝刀点击就送 #include <cs ...

  4. LOJ#6002. 「网络流 24 题」最小路径覆盖

    模板. 1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 //#include<ti ...

  5. 洛谷 - P2764 最小路径覆盖问题(最大流+二分图最小路径覆盖+路径打印)

    题目链接:点击查看 题目大意:给出一个由n个点和m条边组成的有向无环图,现在需要我们求最少可以将n个点分为多少条简单路径,并打印出每一条路径 题目分析:题意挺难懂的..简单来说就是让求二分图最小路径覆 ...

  6. 【网络流24题】魔术球问题(最大流)

    [网络流24题]魔术球问题(最大流) 题面 Cogs 题解 是不是像极了最小路径覆盖? 因此,我们枚举放到哪一个球(也可以二分) 然后类似于最小路径覆盖的连边 因为一根柱子对应一个路径的覆盖 所以,提 ...

  7. 【网络流24题】星际转移问题(最大流)

    [网络流24题]星际转移问题(最大流) 题面 Cogs 题解 因为天数是未知的,所以我们要想办法处理天数 可以选择二分或者依次累加天数 因为数据范围较小,使用二分可能反而复杂度会增高 所以使用不断累加 ...

  8. [网络流24题][CODEVS1922]骑士共存问题(最大流)

    问题描述 传送门 题解 首先介绍ATP神犇的做法: 和方格取数3几乎一样,黑白染色,可以发现能攻击到的点颜色不同. 那么从超级源向每一个黑点连边,容量为1,从每一个白点向超级汇连边,容量为1:从黑点向 ...

  9. 线性规划与网络流24题 运输问题(最裸的费用流了)

    存费用流模板 用sfpa算出最小费用和路径,沿这条路径增广 1 const 2 inf=maxlongint; 3 var 4 n,m:longint; 5 map,a,w:array[0..120, ...

  10. [网络流24题][CODEVS1237]餐巾计划问题(费用流)

    题目描述 传送门 题解 拆点,把每天的点拆成xi和yi,xi表示每一天的脏毛巾,yi表示每一天的新毛巾. 从超级源向xi连边,容量为ri,费用为0: 从yi向超级汇连边,容量为ri,费用为0: 从超级 ...

最新文章

  1. Python怎么利用多核cpu
  2. 无法添加选择的Web部件
  3. HBuilder设置代码自动换行的方法
  4. SAP Spartacus 如何使用 API 从浏览器 local Storage 读取数据
  5. 科学计算机eq7,科学计算器HiEdu 580 Scientific Calculator
  6. python实现搜索之二分查找
  7. 23、jQuery九类选择器/jQuery常用Method-API/jQuery常用Event-API
  8. zabbix3.0.4 邮件告警详细配置
  9. 2019.7.19刷题统计
  10. 电脑计算机无法安3.5,win10 net framework 3.5安装不了的完美解决办法
  11. java sao_JavaScript 的一些SAO操作
  12. 车辆vin信息(含发动机号)
  13. 智慧时代正向我们走来(一)
  14. matlab solve和subs,【MATLAB】matlab中的subs()函数和solve()函数用法
  15. VMware中建立共享文件夹 win7
  16. 如何优雅地删除Redis大键
  17. 糯米网电子商务模式:上线当天销售额600多万元的缘由
  18. 【OJ每日一练】1029 - 字母密码
  19. 乐乐音乐4.0简洁版
  20. 手把手教你使用R语言做出SCI论文中的表二(单因素分析表)(2)

热门文章

  1. Nyoj Fire Station
  2. 【转】MFC中用CFile读取和写入文件2
  3. Swift翻译之-关于Swift
  4. [图论] 树剖LCA
  5. nodejs后台系列--第四篇--koa(二)
  6. systemctl 管理服务命令
  7. nginx根据URL地址、user_agent设备类型、文件扩展名 实现动静分离代理转发
  8. shell编程四剑客之 find
  9. python中测试字符串类型的函数_Python新手学习基础之数据类型——字符串类型
  10. 自动基线校正 python_红外光谱的