有没有大佬可以告诉我为什么我这个能过(没有打错),是数据太弱了,还是我没有理解,我没有拆点直接跑了一个最大匹配,它居然过了。
我的理解是因为是个有向图并且我的最大匹配写的时候link只标记了作为入点的那一半,所以一个点可以作为边的入点和边的出点作用两次,因此不用拆点。
#include <iostream>
#include <algorithm>
using namespace std;
#define visit _visit
#define next _next
#define pb push_back
#define fi first
#define se second
#define endl '\n'
#define fast ios::sync_with_stdio(0), cin.tie(0)
#define int long long
#define ll long long
#define pint pair<int,int>
const int mod = 998244353;
const int maxn = 1001;
const int INF = 0x3f3f3f3f;
void read(int &x){
int f=1;x=0;char s=getchar();
while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();}
x*=f;
}
//ll quick_pow(ll a,ll b) {ll res=1;a%=mod; assert(b>=0); for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}
//ll inv(ll x) {return quick_pow(x, mod-2);}
//----------------------------------------------------------------------------------------------------------------------//
struct node{
int ne,to;
};
node edge[6001<<1];
int head[maxn];
int path[maxn];
int cnt;
void addedge(int a,int b){
edge[cnt].to=b;
edge[cnt].ne=head[a];
head[a]=cnt++;
}
int link[maxn],vis[maxn];
bool dfs(int x){
for(int i=head[x];i!=-1;i=edge[i].ne){
int son=edge[i].to;
if(vis[son]==1){
continue;
}
vis[son]=1;
if(link[son]==0){
link[son]=x;
path[x]=son;
return true;
}
if(dfs(link[son])){
link[son]=x;
path[x]=son;
return true;
}
}
return false;
}
void solve(){
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++){
head[i]=-1;
link[i]=0;
}
for(int i=1;i<=m;i++){
int a,b;
cin>>a>>b;
addedge(a,b);
}
int ans=0;
for(int i=1;i<=n;i++){
for(int i=1;i<=n;i++){
vis[i]=0;
}
ans+=dfs(i);
}
for(int i=1;i<=n;i++){
if(link[i]==0){
int now=i;
while(path[now]!=0){
cout<<now<<" ";
now=path[now];
}
cout<<now<<endl;
}
}
cout<<n-ans<<endl;
}
signed main(){
fast;
int t=1;
//cin>>t;
while(t--){
solve();
}
return 0;
}