二分匹配
#include <stdio.h>
#include<string.h>
const int M = 505;
bool canmatch[M][M];

void initm ( int left, int right )


{

for ( int i=0; i<=left; i++ )

{
for ( int j=0; j<=right; j++ )

{
canmatch[i][j] = false;
}
}
}

int ser(int leftnum,int rightnum,int cur,int* link,bool *used)


{
int i;
for(i=1;i<=rightnum;i++)

{
if( canmatch[cur][i]==1 && !used[i] )

{
used[i]=true;
if(link[i]==0||ser(leftnum,rightnum,link[i],link,used))

{
link[i]=cur;
return true;
}
}
}
return false;
}

int Match( int leftnum ,int rightnum )


{
int ans=0 , i;
bool *used = new bool[(rightnum+1)] ;
int *link = new int [(rightnum+1)] ;
memset(link,0,sizeof(int)*(rightnum+1));
for(i=1;i<=leftnum;i++)

{
memset(used,0,sizeof(bool)*(rightnum+1));
if(ser(leftnum,rightnum,i,link,used))
ans++;
}
return ans;
}

int tab[505][505];

void initt ( int n )


{
for ( int i=0; i<n; i++ )

{
for ( int j=0; j<n; j++ )

{
tab[i][j] = 0;
}
}
}


void cup ( int n )/**//*計算傳遞閉包*/


{
for ( int k=0; k<n; k++ )

{
for ( int i=0; i<n; i++ )

{
for ( int j=0; j<n; j++ )

{
tab[i][j] |= tab[i][k] & tab[k][j];
}
}
}
}

int main ()


{
int n, m;
int b, e;
while ( scanf ( "%d%d", &n, &m ) != EOF && ( n || m ) )

{
initm ( n, n );
initt ( n );
for ( int i=0; i<m; i++ )

{
scanf ( "%d%d", &b, &e );
tab[b-1][e-1] = 1;
}
cup ( n );
for ( i=0; i<n; i++ )

{
for ( int j=0; j<n; j++ )

{
if ( tab[i][j] )

{
canmatch[i+1][j+1] = true;
}
}
}
printf ( "%d\n", n - Match ( n, n ) );
}
return 0;
}

































































































































































