题意如题名,最小路径覆盖。
答案为点数减去最大匹配。
用匈牙利直接跑。
#include <cstdio> #include <cstring> #include <vector> using namespace std; const int N=205; int n,m; int map[N][N]; int fr[N]; int vis[N]; int sum; int in[N]; int le; int fa[N]; vector <int > path[N]; int get(int x) { return x==fa[x]?x:fa[x]=get(fa[x]); } void me(int x,int y) { int fx=get(x),fy=get(y); fa[fx]=fy; } bool find(int x) { for (int i=1;i<=n;i++) { if (map[x][i]&&!vis[i]) { vis[i]=1; if (!fr[i]||find(fr[i])) {fr[i]=x;return 1;} } } return 0; } int main() { register int i,j; scanf("%d %d",&n,&m); for (i=1;i<=m;i++) { int x,y; scanf("%d %d",&x,&y); map[x][y]=1; } for (i=1;i<=n;i++) { memset(vis,0,sizeof(vis)); if (find(i)) sum++; } //memset(vis,0,sizeof(vis)); for (i=1;i<=n;i++) fa[i]=i; for (i=1;i<=n;i++) { if (fr[i]) if (fa[i]!=fa[fr[i]]) me(i,fr[i]); } for (i=1;i<=n;i++) { path[fa[i]].push_back(i); } for (i=1;i<=n;i++) { if (path[i].size()) { for (j=0;j<path[i].size();j++) { printf("%d ",path[i][j]); } printf("\n"); } } printf("%d",n-sum); }