题目链接

  这个……学了一条定理

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

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

  就是这样

  

  这是原图

  

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

  

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

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

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

  代码如下。

  

#include<cstdio>
#include<cstring>
#include<cctype>
#include<algorithm>
#include<queue>
#include<cstdlib>
#define maxn 3000
#define maxm 60000
using namespace std;
inline long long read(){
long long num=,f=;
char ch=getchar();
while(!isdigit(ch)){
if(ch=='-') f=-;
ch=getchar();
}
while(isdigit(ch)){
num=num*+ch-'';
ch=getchar();
}
return num*f;
} inline int count(int i){ return i&?i+:i-; } struct Edge{
int next,to,val;
}edge[maxm*];
int head[maxn*],num;
inline void addedge(int from,int to,int val){
edge[++num]=(Edge){head[from],to,val};
head[from]=num;
}
inline void add(int from,int to,int val){
addedge(from,to,val);
addedge(to,from,);
} bool vis[maxn];
int dfn[maxn];
int list[maxn*];
int Start,End;
int road[maxn*];
int n,m;
bool flag; bool bfs(){
memset(vis,,sizeof(vis));
queue<int> q; dfn[Start]=; vis[Start]=; q.push(Start);
while(!q.empty()){
int from=q.front(); q.pop();
for(int i=head[from];i;i=edge[i].next){
int to=edge[i].to;
if(vis[to]||edge[i].val<=) continue;
vis[to]=;
dfn[to]=dfn[from]+;
q.push(to);
}
}
return vis[End];
} int dfs(int x,int val){
//printf("%d %d\n",x,val);
if(val==||x==End) return val;
vis[x]=; int flow=;
for(int &i=list[x];i;i=edge[i].next){
int to=edge[i].to;
if(vis[to]||dfn[to]!=dfn[x]+||edge[i].val<=) continue;
int now=dfs(to,min(val,edge[i].val));
val-=now; edge[i].val-=now; flow+=now; edge[count(i)].val+=now;
if(val<=){
road[x]=to;
break;
}
}
if(flow!=val) dfn[x]=-;
return flow;
} int maxflow(){
int ans=;
while(bfs()){
memset(vis,,sizeof(vis));
for(int i=Start;i<=End;++i) list[i]=head[i];
int now=dfs(Start,0x7fffffff);
if(!now) break;
ans+=now;
}
return ans;
} int main(){
n=read(),m=read();End=n*+;
for(int i=;i<=n;++i){
add(Start,i,);
add(i+n,End,);
}
for(int i=;i<=m;++i){
int from=read(),to=read();
add(from,to+n,);
}
int ans=maxflow();
memset(vis,,sizeof(vis));
for(int i=;i<=n;++i){
if(road[i]==) continue;
int now=i;
while(now!=End&&now){
printf("%d ",now>n?now-=n:now);
int x=road[now]; road[now]=;
now=x;
}
printf("\n");
}
printf("%d",n-ans);
return ;
}

【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. 用NPOI操作EXCEL-锁定列CreateFreezePane()

    public void ExportPermissionRoleData(string search, int roleStatus) { var workbook = new HSSFWorkboo ...

  2. [VC]在VC++中实现让程序只运行一个实例的方法且实现该实例

    方法一: 有时候在开发应用程序时,希望控制程序运行唯一的实例.例如,最常用的mp3播放软 件Winamp,由于它需要独占计算机中的音频设备,因此该程序只允许自身运行唯一的一个例程.在Visual C+ ...

  3. What is a meta-class in Objective-C?

    http://www.cocoawithlove.com/2010/01/what-is-meta-class-in-objective-c.html In this post, I look at ...

  4. JEECMS开发问题汇总

    1 添加Controller 将controller文件放在com.jeecms.cms.action.front包中, 图1.1 然后在jeecms-servlet-front-action.xml ...

  5. 解决升级mac os X EI Capitan后遇到LibclangError: dlopen(libclang.dylib, 6): image not found.的问题

    打开文件./frameworks/cocos2d-x/tools/bindings-generator/clang/cindex.py 把第 3395 行 改为 : library = cdll.Lo ...

  6. Chunky Monkey-freecodecamp算法题目

    Chunky Monkey(猴子吃香蕉, 分割数组) 要求 把一个数组arr按照指定的数组大小size分割成若干个数组块. 思路 利用size值和while语句确定切割数组的次数(定义temp将siz ...

  7. Android驱动开发读书笔记五

    第五章 本章介绍了S3C6410开发板的功能,开发板的不同主要是在烧录嵌入式系统的方式不同,以及如何在此开发板上安装Android. 1.安装串口调试工具minicom 首先需要一根USB转串口线,由 ...

  8. 基础的Mapgis三维二次开发-插件式

    最近在做一个杭州石油的项目开发一个小系统. 1.命令必须是 ICommand 的派生类 using System; using System.Collections.Generic; using Sy ...

  9. 【启发式拆分】bzoj5200: [NWERC2017]Factor-Free Tree

    和bzoj4059: [Cerc2012]Non-boring sequences非常相似 Description 一棵Factor-Free Tree是指一棵有根二叉树,每个点包含一个正整数权值,且 ...

  10. redis学习笔记(2)

    redis学习笔记第二部分 --配置文件介绍 二,解析redis的配置文件redis.conf常见配置参数说明redis.conf 配置项说明如下:1. Redis默认不是以守护进程的方式运行,可以通 ...