思路:
首先明确,这题就是要求最小路径覆盖
然后最小路径覆盖=总点数-匹配数
至于怎么证明还搞不懂
c o d e code code
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int n, m, ans;
int dis[1000][1000], head[1011], tot;
int v[1000], father[1010];
struct node
{
int to, next;
}b[1001000];
void add(int x, int y)
{
b[++tot]=(node){y, head[x]};
head[x]=tot;
}
bool dfs(int x)
{
for(int i=head[x]; i; i=b[i].next)
{
int y=b[i].to;
if(v[y])
continue;
v[y]=1;
int sum=father[y];
father[y]=x;
if(sum==0||dfs(sum))
return 1;
father[y]=sum;
}
return 0;
}
int main()
{
scanf("%d%d", &n, &m);
for(int i=1; i<=m; i++)
{
int x, y;
scanf("%d%d", &x, &y);
dis[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(i!=k&&k!=j&&i!=j)
dis[i][j]|=dis[i][k] && dis[k][j];
for(int i=1; i<=n; i++)
for(int j=1; j<=n; j++)
if(dis[i][j])
add(i, j);
for(int i=1; i<=n; i++)
{
memset(v, 0, sizeof(v));
dfs(i);
}
int ans=0;
for(int i=1; i<=n; i++)
if(father[i]!=0)
ans++;
printf("%d", n-ans);
return 0;
}