最大独立点集=点数-最大匹配=点数-最小点覆盖=最小边覆盖
先floyed传递闭包
然后匈牙利算法
#include<bits/stdc++.h>
using namespace std;
const int N=2e2+10;
int G[N][N],vis[N],match[N],n;
bool dfs(int x){
for(int i=1;i<=n;++i){
if(G[x][i]&&vis[i]==0){
vis[i]=1;
if(!match[i]||dfs(match[i])){
match[i]=x;return 1;
}
}
}
return 0;
}
int main(){
int T;cin>>T;while(T--){
memset(match,0,sizeof match);memset(G,0,sizeof G);
int m;cin>>n>>m;int ans=n;while(m--){
int x,y;scanf("%d%d",&x,&y);G[x][y]=1;
}
for(int k=1;k<=n;++k)for(int i=1;i<=n;++i)for(int j=1;j<=n;++j){
if(G[i][k]&&G[k][j])G[i][j]=1;
}
for(int i=1;i<=n;++i){
memset(vis,0,sizeof vis);
if(dfs(i))--ans;
}
cout<<ans<<endl;
}
}