K

题意:给一个有向无环图,求出来最小路径覆盖,注意一个点可能会被多条路径重复
分析:因为有可能多条路径走一个点,可又能会造成匹配的不完全,所以先进行一次闭包传递(floyd),然后再用二分匹配的方法求出来最大匹配即可。
*********************************************************************.
#include<stdio.h>
#include<string.h>
#include<queue>
using namespace std;

const int MAXN = 505;
const int oo = 1e9+7;

bool G[MAXN][MAXN], used[MAXN];
int My[MAXN], N, M;

void Floyd()
{
    for(int k=1; k<=N; k++)
    for(int i=1; i<=N; i++)
    for(int j=1; j<=N; j++)
    {
        if( G[i][k] && G[k][j] )
            G[i][j] = true;
    }
}
bool Find(int i)
{
    for(int j=1; j<=N; j++)
    {
        if( G[i][j] && used[j] == false )
        {
            used[j] = true;
            if( !My[j] || Find( My[j] ) )
            {
                My[j] = i;
                return true;
            }
        }
    }

    return false;
}

int main()
{
    while(scanf("%d%d", &N, &M), N+M)
    {
        int i, u, v, ans=0;

        memset(G, falsesizeof(G));
        memset(My, falsesizeof(My));

        while(M--)
        {
            scanf("%d%d", &u, &v);
            G[u][v] = true;
        }

        Floyd();

        for(i=1; i<=N; i++)
        {
            memset(used, falsesizeof(used));
            if( Find(i) == true )
                ans++;
        }

        printf("%d ", N-ans);
    }

    return 0;
}
原文地址:https://www.cnblogs.com/liuxin13/p/4700201.html