这题一开始WA掉了,因为把他当做简单的最小路径覆盖做了,但是这题并不是,这题的点是可以重复经过的,而最小路径覆盖的匹配中一个点只能经过一次,所以我们要把图中能到的点都建立直达边,这样就可以直接用最小路径覆盖去做了。
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#define maxn 505
#define mem(a) memset(a, 0, sizeof(a))
using namespace std;
bool map[maxn][maxn], vis[maxn];
int lk[maxn], num;
bool dfs(int a)
{
int i;
for(i = 1;i <= num;i++)
{
if(!vis[i]&&map[a][i])
{
vis[i] = 1;
if(lk[i] == -1||dfs(lk[i]))
{
lk[i] = a;
return true;
}
}
}
return false;
}
int res()
{
int i;
int ress = 0;
memset(lk, -1, sizeof(lk));
for(i = 1;i <= num;i++)
{
mem(vis);
if(dfs(i))
ress++;
}
return ress;
}
int main(int argc, char *argv[])
{
int ans, m, a, b, i, j, k;
for(;;)
{
mem(map);
scanf("%d%d", &num, &m);
if(num == 0&&m == 0)
break;
for(i = 0;i < m;i++)
{
scanf("%d%d", &a, &b);
map[a][b] = 1;
}
for(i = 1;i < num;i++)
{
for(j = (i + 1);j <= num;j++)
{
if(!map[i][j])
{
for(k = (i + 1);k < j;k++)
{
if(map[i][k]&&map[k][j])
{
map[i][j] = 1;
break;
}
}
}
}
}
ans = res();
printf("%d\n", num - ans);
}
return 0;
}