洛谷 P2764 最小路径覆盖问题 (网络流24题)

版权声明:欢迎转载欢迎评论! https://blog.csdn.net/rabbit_ZAR/article/details/82845786

题目:最小路径覆盖问题

思路:
把每个点拆成两个点,其中一个作为入点,另一个作为出点。
然后对于这个二分图求最大匹配输出。
之前因为int没加返回值,系统开了O2优化RE了好久QAQ……

代码:

#pragma GCC optimize(2)
#include<bits/stdc++.h>
using namespace std;

#define maxn 150
#define maxm 6000
#define read(x) scanf("%d",&x);

int n,m;
vector<int> g[2*maxn+5];

void readin() {
	read(n);
	read(m);
	for(int i=1; i<=m; i++) {
		int x,y;
		read(x);
		read(y);
		g[x].push_back(y+n);
	}
}

int use[maxn*2+5],match[maxn*2+5];

int dfs(int x) {
	if(use[x]) return false;
	use[x]=true;
	for(int i=0; i<g[x].size(); i++) {
		int y=g[x][i];
		if(!match[y]||dfs(match[y])) {
			match[x]=y;
			match[y]=x;
			return true;
		}
	}
	return false;
}

void slv() {
	for(int i=1; i<=n; i++) {
		dfs(i);
		memset(use,0,sizeof(use));
	}
}

void print() {
	int ans=0;
	for(int i=1;i<=n;i++) {
		if(use[i]) continue;
		ans++;
		int x=i+n;
		do{
			x-=n;
			use[x]=true;
			printf("%d ",x);
		} while(x=match[x]);
		printf("\n");
	}
	printf("%d\n",ans);
}

int main() {
	readin();
	slv();
	print();
	return 0;
}

猜你喜欢

转载自blog.csdn.net/rabbit_ZAR/article/details/82845786