HDU-1150 HK二分图最小点覆盖

来源:互联网 发布:富坚义博 知乎 编辑:程序博客网 时间:2024/05/17 15:18
//二分图最小点覆盖 = 二分图最大匹配#include<stdio.h>#include<string.h>#include<queue>using namespace std;const int maxn = 105;const int inf = 1<<30;int nx,ny,m;int dis;int map[maxn][maxn];int cx[maxn],cy[maxn];int dx[maxn],dy[maxn];bool vis[maxn];//Hopcroft-Karp算法 有点类似dinic 都是先对图BFS分层再沿层数DFS找增广路//***************************************************************************bool searchpath()      //BFS 对二分图分层{    queue<int>que;    dis = inf;    memset( dx,-1,sizeof(dx) );    memset( dy,-1,sizeof(dy) );    for( int i = 1; i <= nx; i ++ )   //找到x集合所有未被匹配的点压入队列中    {        if( cx[i] == -1 )        {            que.push(i);            dx[i] = 0;        }    }    while( !que.empty() )    {        int u = que.front(); que.pop();        if( dx[u] > dis )            break;        for( int v = 1; v <= ny; v ++ )        {            if( map[u][v] && dy[v] == -1 )            {                dy[v] = dx[u] + 1;                if( cy[v] == -1 )                    dis = dy[v];                else                {                    dx[cy[v]] = dy[v] + 1;                    que.push( cy[v] );                }            }        }    }    return dis != inf;}bool findpath( int u )   //沿着层数DFS{    for( int v = 1; v <= ny; v ++ )    {        if( map[u][v] && !vis[v] && dy[v] == dx[u] + 1 )        {            vis[v] = 1;            if( cy[v] != -1 && dy[v] == dis )                continue;            if( cy[v] == -1 || findpath( cy[v] ) )            {                cy[v] = u;                cx[u] = v;                return true;            }        }    }    return false;}int MaxMatch(){    int ans = 0;    memset( cx,-1,sizeof(cx) );    memset( cy,-1,sizeof(cy) );    while( searchpath() )    {        memset( vis,0,sizeof(vis) );        for( int i = 1; i <= nx; i ++ )        {            if( cx[i] == -1 )            {                                ans += findpath( i );            }        }    }    return ans;}//****************************************************************int main(){    int k,x,y;    while( scanf("%d",&nx ) != EOF , nx )    {        scanf("%d%d",&ny,&m);        memset( map,0,sizeof(map) );        for( int i = 1; i <= m; i++ )        {            scanf("%d%d%d",&k,&x,&y);            map[x][y] = 1;        }        printf("%d\n", MaxMatch() );    }}