分析
题意就是选到的点都不能直接互相到达。
首先我们要求这个DAG的最长反链长度。
反链的定义是:“反链(antichain)是一个偏序集S的子集,其中任意两个元素不可比较”
根据dilworth定理,得出结论:最小链覆盖=最长反链长度。
最小链覆盖就是n-最大匹配数ans。
做floyed 缩点,变为不可相交。
上代码
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
int n,m,ans,f[201][201],v[201],p[201];
bool check(int x)
{
for(int i=1;i<=n;i++)//遍历边
{
if(f[x][i]&&!p[i])//找到能连接的
{
p[i]=1;
if(!v[i]||check(v[i]))//如果已经有人连接,尝试替换,作为一个匹配
{
v[i]=x;
return true;
}
}
}
return false;
}
int main()
{
cin>>n>>m;
for(int i=1;i<=m;i++)
{
int x,y;
cin>>x>>y;
f[x][y]=1;
}
for(int i=1;i<=n;i++)//floyed缩点
{
for(int j=1;j<=n;j++)
{
if(!f[i][j]&&i!=j)
{
for(int k=1;k<=n;k++)
{
if(f[i][k]&&f[k][j])//判断连通
{
f[i][j]=1;
}
}
}
}
}
for(int i=1;i<=n;i++)
{
memset(p,0,sizeof(p));
if(check(i)) ans++;
}
cout<<n-ans;
return 0;
}