点可重复的路径覆盖问题用匈牙利算法+floyd闭包来求解。
#include <queue>
#include <stack>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <limits.h>
#include <string.h>
#include <algorithm>
#define MAX 550
using namespace std;
bool map[MAX][MAX],used[MAX];
int mat[MAX];
void floyd(int n)
{
int i,j,k;
for(k=1;k<=n;k++)
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
{
map[i][j]=(map[i][j]||map[i][k]&&map[k][j]);
}
}
bool Augment(int x,int n)
{
int i;
for(i=1; i<=n; i++)
if( !used[i] && map[x][i] )
{
used[i] = true;
if( !mat[i] || Augment(mat[i],n) )
{
mat[i] = x;
return true;
}
}
return false;
}
int Hungary(int n,int m)
{
int i,sum = 0;
memset(mat,0,sizeof(mat));
for(i=1; i<=n; i++)
{
memset(used,false,sizeof(used));
if( Augment(i,m) )
sum++;
}
return sum;
}
int main()
{
int n,m,from,to,i,j,k;
while( ~scanf("%d%d",&n,&m) )
{
if( n == m && n == 0 )
break;
memset(map,false,sizeof(map));
while( m-- )
{
scanf("%d%d",&from,&to);
map[from][to] = true;
}
floyd(n);
int ans = Hungary(n,n);
printf("%d\n",n-ans);
}
return 0;
}