二分匹配
#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; }
|
|
| 日 | 一 | 二 | 三 | 四 | 五 | 六 |
---|
25 | 26 | 27 | 28 | 29 | 30 | 31 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 1 | 2 | 3 | 4 | 5 |
|
公告
决定从线程开始!!
常用链接
留言簿(6)
随笔档案
搜索
最新评论
阅读排行榜
评论排行榜
|
|