#6002. 「网络流 24 题」最小路径覆盖
内存限制:256 MiB
时间限制:1000 ms
标准输入输出
题目类型:传统
评测方式:Special Judge
上传者: 匿名
题目描述
输入格式
输出格式
样例
数据范围与提示
这题本来是用网络流做的,但是用二分匹配也很方便就用 匹配做了
直接拆点 连边 就是二分匹配里常见的 独立子集的模板
#include <iostream>
#include <cstdio>
#include <cstring>
#include <bits/stdc++.h>
using namespace std;
typedef long long LL ;
const int inf = 500;
const int N = 1000;
const double eps = 1e-7;
struct node
{
int to, next;
}p[1000000];
int head[N], cnt;
int match[N], w[N], vis[N];
void init()
{
memset(head,-1,sizeof(head));
memset(match,-1,sizeof(match));
memset(w,0,sizeof(w));
cnt=0;
return ;
}
void add(int u,int v)
{
p[cnt].to=v,p[cnt].next=head[u];head[u]=cnt++;
return ;
}
int dfs(int u)
{
for(int i=head[u];i!=-1;i=p[i].next)
{
int v=p[i].to;
if(vis[v]) continue;
vis[v]=1;
if(match[v]==-1||dfs(match[v]))
{
match[v]=u,w[u]=v;
return 1;
}
}
return 0;
}
int ans[N];
int main()
{
init();
int n, m;
scanf("%d %d", &n, &m);
for(int i=1;i<=m;i++)
{
int a, b;
scanf("%d %d", &a, &b);
add(n+a,b);
}
for(int i=n+1;i<=2*n;i++)
{
memset(vis,0,sizeof(vis));
dfs(i);
}
int k=0;
for(int i=1;i<=n;i++) if(match[i]==-1) ans[++k]=i;
for(int i=1;i<=k;i++)
{
printf("%d",ans[i]);
int x=n+ans[i];
while(w[x])
{
printf(" %d",w[x]);
x=n+w[x];
}
puts("");
}
printf("%d\n",k);
return 0;
}