版权声明:欢迎转载欢迎评论! 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;
}