最小路径覆盖问题

题目

求有向无环图的最小路径覆盖(可以从任意一个点开始)


题目链接:洛谷P 2764


二分图性质:最小路径覆盖 == 顶点数 - 最大匹配数

所以此题我们可以转化为求最大匹配来做,但是麻烦的是输出路径。


考虑建图:

我们可以把点拆成两个点,分别为入点和出点,让超级源点S连向每个点的入点,让每个点的出点连向超级汇点T,然后如果u能到达v,那么就让u的入点连向v的出点即可。(建图完成)

然后跑一遍最大流,答案就是总的点数 n - dinic()

考虑输出路径:

我们输出路径,主要就是要找到每个边集合开始的边,很多人都用并查集来维护边的关系,但是我觉得完全没有必要,我们考虑一下开始的边的关系,我们可以发现如果当前的点的出点所连接的点,如果没有流量流过来,那么这个点就是开始的点。所以我们可以判断每个点的出点,如果所有点到它的流量都是1,然后我们dfs一遍输出即可。


AC代码:

#pragma GCC optimize(2)
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=310,M=120010;
int n,m,h[N],s,t,vis[N],f[N];
int head[N],to[M],w[M],nex[M],tot=1;
inline void ade(int a,int b,int c){
	to[++tot]=b; w[tot]=c; nex[tot]=head[a]; head[a]=tot;
}
inline void add(int a,int b,int c){
	ade(a,b,c);	ade(b,a,0);
}
int find(int x){
	return x==f[x]?x:f[x]=find(f[x]);
}
int bfs(){
	memset(h,0,sizeof h);	queue<int> q;	q.push(s);	h[s]=1;
	while(q.size()){
		int u=q.front();	q.pop();
		for(int i=head[u];i;i=nex[i]){
			if(w[i]&&!h[to[i]]){
				h[to[i]]=h[u]+1;	q.push(to[i]);
			}
		}
	}
	return h[t];
}
int dfs(int x,int f){
	if(x==t)	return f;
	int fl=0;
	for(int i=head[x];i&&f;i=nex[i]){
		if(w[i]&&h[to[i]]==h[x]+1){
			int mi=dfs(to[i],min(w[i],f));
			w[i]-=mi;	w[i^1]+=mi;	fl+=mi;	f-=mi;
		}
	}
	if(!fl)	h[x]=-1;
	return fl;
}
int dinic(){
	int res=0;
	while(bfs())	res+=dfs(s,0x3f3f3f3f);
	return res;
}
void out(int x){
	printf("%d ",x);
	for(int i=head[x*2-1];i;i=nex[i]){
		if(!w[i]&&to[i]!=s)	out(to[i]/2);
	}
}
signed main(){
	cin>>n>>m;	s=0,t=2*n+2;
	for(int i=1;i<=n;i++){
		add(s,i*2-1,1);	add(i*2,t,1);
	}
	for(int i=1;i<=m;i++){
		int a,b;	cin>>a>>b;	add(a*2-1,b*2,1);
	}
	int res=n-dinic();
	for(int i=1;i<=n;i++){
		int flag=0;
		for(int j=head[i*2];j&&!flag;j=nex[j]){
			if(to[j]!=t&&!w[j^1])	flag++;
		}
		if(!flag)	out(i),puts("");
	}
	cout<<res<<endl;
	return 0;
}

全部评论

相关推荐

11-13 10:17
门头沟学院 Java
昨天面美团,jvm,juc问的好深啊,感觉小林coding不太够喔,牛油们有没有什么推荐的八股网站嘛🕒&nbsp;岗位/面试时间👥&nbsp;面试题目🤔&nbsp;面试感受
明天不下雨了:小林Coding:https://xiaolincoding.com/ 全栈哥:https://www.pdai.tech/ Guide哥:https://javaguide.cn/ 秀哥:https://interviewguide.cn/ 沉默王二:https://javabetter.cn/home.html 磊哥:https://www.javacn.site/interview/basic/ 小傅哥:https://bugstack.cn/ 源码哥:https://doocs.github.io/source-code-hunter/#/ 各大厂的公众号技术文章和一些经典的书籍
面试太紧张了怎么办?
点赞 评论 收藏
分享
安静的鲸鱼offer...:神仙级别hr,可遇不可求,甚至他可能也是突然有感而发。只能说遇上是件幸事。
秋招开始捡漏了吗
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务