最小路径覆盖数=顶点数n-最大匹配数;
一个PXP的有向图中,路径覆盖就是在图中找一些路径,使之覆盖了图中的所有顶点,且任何一个顶点有且只有一条路径与之关联;(如果把这些路径中的每条路径从它的起始点走到它的终点,那么恰好可以经过图中的每个顶点一次且仅一次);如果不考虑图中存在回路,那么每条路径就是一个弱连通子集.
由上面可以得出:
2.如果存在一路径p1,p2,......pk,其中p1 为起点,pk为终点,那么在覆盖图中,顶点p1,p2,......pk不再与其它的顶点之间存在有向边.
#include<iostream> #include<cstdio> #include<cstdlib> #include<algorithm> #include<cmath> #include<queue> #include<set> #include<map> #include<cstring> #include<vector> using namespace std; bool G[324][324],visit[324]; int match[324]; bool patch( int num ,int N ){ for( int i = 1 ; i <= N ; i ++){ if( !visit[i] && G[num][i] ){ visit[i] = true; if( match[i] == 0 || patch( match[i] , N ) ){ match[i] = num; return true; } } } return false; } int main( ) { int town,N,K,x,y; while( scanf( "%d",&town )==1 ){ while( town --){ memset( G, 0 ,sizeof( G ) ); memset( match , 0 ,sizeof( match ) ); scanf( "%d %d",&N,&K ); for( int i = 1; i <= K ; i++ ){ scanf( "%d %d",&x,&y ); G[x][y] = 1; } int ans = 0; for( int i =1 ; i <= N ; i ++ ){ memset( visit , 0 , sizeof( visit ) ); if( patch( i , N ) ) ans ++; } printf( "%d\n",N-ans ); } } //system( "pause" ); return 0; }