题目链接

  这个……学了一条定理

  最小路径覆盖=原图总点数-对应二分图最大匹配数

  这个对应二分图……是什么呢?

  就是这样

  

  这是原图

  

  这是拆点之后对应的二分图。

  

  然后咱们的目标就是从这张图上跑出个最大流来,然后用原图的总点数减去就是答案。

  至于记录路径……我发现有一个规律是可以在Dinic跑DFS的时候记。

  别的我不知道了。因为我只会Dinic。

  代码如下。

  

  1. #include<cstdio>
  2. #include<cstring>
  3. #include<cctype>
  4. #include<algorithm>
  5. #include<queue>
  6. #include<cstdlib>
  7. #define maxn 3000
  8. #define maxm 60000
  9. using namespace std;
  10. inline long long read(){
  11. long long num=,f=;
  12. char ch=getchar();
  13. while(!isdigit(ch)){
  14. if(ch=='-') f=-;
  15. ch=getchar();
  16. }
  17. while(isdigit(ch)){
  18. num=num*+ch-'';
  19. ch=getchar();
  20. }
  21. return num*f;
  22. }
  23.  
  24. inline int count(int i){ return i&?i+:i-; }
  25.  
  26. struct Edge{
  27. int next,to,val;
  28. }edge[maxm*];
  29. int head[maxn*],num;
  30. inline void addedge(int from,int to,int val){
  31. edge[++num]=(Edge){head[from],to,val};
  32. head[from]=num;
  33. }
  34. inline void add(int from,int to,int val){
  35. addedge(from,to,val);
  36. addedge(to,from,);
  37. }
  38.  
  39. bool vis[maxn];
  40. int dfn[maxn];
  41. int list[maxn*];
  42. int Start,End;
  43. int road[maxn*];
  44. int n,m;
  45. bool flag;
  46.  
  47. bool bfs(){
  48. memset(vis,,sizeof(vis));
  49. queue<int> q; dfn[Start]=; vis[Start]=; q.push(Start);
  50. while(!q.empty()){
  51. int from=q.front(); q.pop();
  52. for(int i=head[from];i;i=edge[i].next){
  53. int to=edge[i].to;
  54. if(vis[to]||edge[i].val<=) continue;
  55. vis[to]=;
  56. dfn[to]=dfn[from]+;
  57. q.push(to);
  58. }
  59. }
  60. return vis[End];
  61. }
  62.  
  63. int dfs(int x,int val){
  64. //printf("%d %d\n",x,val);
  65. if(val==||x==End) return val;
  66. vis[x]=; int flow=;
  67. for(int &i=list[x];i;i=edge[i].next){
  68. int to=edge[i].to;
  69. if(vis[to]||dfn[to]!=dfn[x]+||edge[i].val<=) continue;
  70. int now=dfs(to,min(val,edge[i].val));
  71. val-=now; edge[i].val-=now; flow+=now; edge[count(i)].val+=now;
  72. if(val<=){
  73. road[x]=to;
  74. break;
  75. }
  76. }
  77. if(flow!=val) dfn[x]=-;
  78. return flow;
  79. }
  80.  
  81. int maxflow(){
  82. int ans=;
  83. while(bfs()){
  84. memset(vis,,sizeof(vis));
  85. for(int i=Start;i<=End;++i) list[i]=head[i];
  86. int now=dfs(Start,0x7fffffff);
  87. if(!now) break;
  88. ans+=now;
  89. }
  90. return ans;
  91. }
  92.  
  93. int main(){
  94. n=read(),m=read();End=n*+;
  95. for(int i=;i<=n;++i){
  96. add(Start,i,);
  97. add(i+n,End,);
  98. }
  99. for(int i=;i<=m;++i){
  100. int from=read(),to=read();
  101. add(from,to+n,);
  102. }
  103. int ans=maxflow();
  104. memset(vis,,sizeof(vis));
  105. for(int i=;i<=n;++i){
  106. if(road[i]==) continue;
  107. int now=i;
  108. while(now!=End&&now){
  109. printf("%d ",now>n?now-=n:now);
  110. int x=road[now]; road[now]=;
  111. now=x;
  112. }
  113. printf("\n");
  114. }
  115. printf("%d",n-ans);
  116. return ;
  117. }

【Luogu】P2764最小路径覆盖(拆点求最大匹配)的更多相关文章

  1. Luogu P2764 最小路径覆盖问题(二分图匹配)

    P2764 最小路径覆盖问题 题面 题目描述 «问题描述: 给定有向图 \(G=(V,E)\) .设 \(P\) 是 \(G\) 的一个简单路(顶点不相交)的集合.如果 \(V\) 中每个顶点恰好在 ...

  2. luogu P2764 最小路径覆盖问题

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

  3. LUOGU P2764 最小路径覆盖问题 (最小路径点覆盖)

    解题思路 有向图最小路径点覆盖问题,有这样的结论就是有向图最小路径点覆盖等于n-拆点二分图中最大匹配.具体怎么证明不太知道..输出方案时找到所有左部未匹配的点一直走$match​$就行了. #incl ...

  4. 【luogu P2764 最小路径覆盖问题】 模板

    题目链接:https://www.luogu.org/problemnew/show/P2764 把每个点在左边建一遍右边建一遍,再加上源点汇点,跑最大流,n-最大流就是答案. #include &l ...

  5. 洛谷 P2764 最小路径覆盖问题 解题报告

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

  6. Luogu 2764 最小路径覆盖问题 / Libre 6002 「网络流 24 题」最小路径覆盖 (网络流,最大流)

    Luogu 2764 最小路径覆盖问题 / Libre 6002 「网络流 24 题」最小路径覆盖 (网络流,最大流) Description 给定有向图G=(V,E).设P是G的一个简单路(顶点不相 ...

  7. P2764 最小路径覆盖问题 网络流重温

    P2764 最小路径覆盖问题 这个题目之前第一次做的时候感觉很难,现在好多了,主要是二分图定理不太记得了,二分图定理 知道这个之后就很好写了,首先我们对每一个点进行拆点,拆完点之后就是跑最大流,求出最 ...

  8. 洛谷 P2764 最小路径覆盖问题【最大流+拆点+路径输出】

    题目链接:https://www.luogu.org/problemnew/show/P2764 题目描述 «问题描述: 给定有向图G=(V,E).设P 是G 的一个简单路(顶点不相交)的集合.如果V ...

  9. 网络流二十四题之P2764 最小路径覆盖问题

    题目描述 给定有向图 G=(V,E)G=(V,E) .设 PP 是 GG 的一个简单路(顶点不相交)的集合.如果 VV 中每个定点恰好在PP的一条路上,则称 PP 是 GG 的一个路径覆盖.PP中路径 ...

随机推荐

  1. 10.1 plan

    1951    [Sdoi2010]古代猪文  Sdoi2010 Contest2   807 1928 1566    [NOI2009]管道取珠       806 1429 2756    [S ...

  2. DROP OPERATOR CLASS - 删除一个操作符类

    SYNOPSIS DROP OPERATOR CLASS name USING index_method [ CASCADE | RESTRICT ] DESCRIPTION 描述 DROP OPER ...

  3. PAT (Basic Level) Practise (中文)- 1008. 数组元素循环右移问题 (20)

    一个数组A中存有N(N>0)个整数,在不允许使用另外数组的前提下,将每个整数循环向右移M(M>=0)个位置,即将A中的数据由(A0A1……AN-1)变换为(AN-M …… AN-1 A0  ...

  4. Servlet的引入(即加入Servlet)

    今天讲的Servlet是根据上一章节<创建一个学生信息表,与页面分离>而结合. 一.看图分析 此模式有问题: 1.jsp需要呼叫javabean StudentService stuSer ...

  5. 关于SQL语言的初步认识

    关于SQL语言的初步认识 1.一个SQL数据库是表(Table)的集合,它由一个或多个SQL模式定义. 2.一个SQL表由行集构成,一行是列的序列(集合),每列与行对应一个数据项. 3.一个表或者是一 ...

  6. 解决cocos2dx 3.x 导入cocostudio的ui界面出现错位问题

    笔者今天发现导入cocostudio的ui界面时,会有部分控件出现错位的现象,后来我看了一下源码,发现是部分控件是没有继承 Layout类,导致不能设置控件位置造成,原因可以看看cocos2dx 源码 ...

  7. cocos2dx 单张图片加密

    cocos2dx 已经封装好读取加密的prv文件的方法,打开texturepacker,导入一张图片,在content protection中写入密钥,在texture format中选择prv格式 ...

  8. [vijos]P1514 天才的记忆

    背景 神仙飞啊飞 描述 从前有个人名叫W and N and B,他有着天才般的记忆力,他珍藏了许多许多的宝藏.在他离世之后留给后人一个难题(专门考验记忆力的啊!),如果谁能轻松回答出这个问题,便可以 ...

  9. 在Keras中导入测试数据的方法

    https://blog.csdn.net/ethantequila/article/details/80322425?utm_source=blogxgwz2

  10. windows10蓝屏page fault in nonpaged area

    Windows系统最让人头疼的问题就是蓝屏了,总是出现得那么莫名其妙,而且造成原因也是千奇百怪的.所以,对于电脑蓝屏,系统迷也无法一次性讲清楚.前天,我的电脑就经历过这样的蓝屏page fault i ...