原文:http://www.cnblogs.com/jackiesteed/articles/2043934.html
DAG的最小路径覆盖是指找最小数目的互相不相交的有向路径,满足DAG的所有顶点都被覆盖.

首先给出公式:DAG的最小路径覆盖数=DAG图中的节点数-相应二分图中的最大匹配数.

那么对应一个DAG,如何构造相应的二分图?对于DAG中的一个顶点p,二分图中有两个顶点p和p',对应DAG中的一条有向边p->q,二分图中有p-q'的一条无向边.二分图中p属于S集合,p'属于T集合.
下面我们来解释上面公式为什么成立,思路参考 baihacker神牛:


上图中,对应左边的DAG建立构造右边的二分图,可以找到二分图的一个最大匹配M:1-3',3-4',那么M中的这两条匹配边怎样对应DAG中的路径的边?
使二分图中一条边对应DAG中的一条有向边,1-3'对应DAG图中的有向边1->3,这样DAG中1就会有一个后继顶点(3会是1的唯 一后继,因为二分图中一个顶点至多关联一条边!),所以1不会成为DAG中一条路径中的结尾顶点,同样,3-4'对应DAG中3->4,3也不会成 为结尾顶点,那么原图中总共4个顶点,减去2个有后继的顶点,就剩下没有后继的顶点,即DAG路径的结尾顶点,而每个结尾顶点正好对应DAG中的一条路 径,二分图中寻找最大匹配M,就是找到了对应DAG中的非路径结尾顶点的最大数目,那么DAG中顶点数-|M|就是DAG中结尾顶点的最小数目,即DAG 的最小路径覆盖数.
 

题目描述

Spike the bounty hunter is tracking another criminal through space. Luckily for him hyperspace travel has made the task of visiting several planets a lot easier. Each planet has a number of Astral Gates; each gate connects with a gate on another planet. These hyperspace connections are, for obvious safety reasons, one-way only with one gate being the entry point and the other gate being the exit point from hyperspace. Furthermore, the network of hyperspace connections must be loop-free to prevent the Astral Gates from exploding, a tragic lesson learned in the gate accident of 2022 that destroyed most of the moon.
While looking at his star map Spike wonders how many friends he needs to conduct a search on every planet. Each planet should not be visited by more than one friend otherwise the criminal might get suspicious and flee before he can be captured. While each person can start at a planet of their choosing and travel along the hyperspace connections from planet to planet they are still bound by the limitations of hyperspace travel.

输入

The input begins with an integer N specifying the number of planets (0 < N ≤ 1000). The planets are numbered from 0 to N −1. The following N lines specify the hyperspace connections.
The i-th of those lines first contains the count of connections K (0 ≤ K ≤ N −1) from planet i followed by K integers specifying the destination planets.

输出

Output the minimum number of persons needed to visit every planet.

样例输入

4
1 1
1 2
0
1 1

样例输出

2


题意:
给n个点,每个点m[i]条出边,每个点只能走一次
问至少需要多少条路径走完所有的点
/* ***********************************************
//Author        :devil
//Created Time  :2016/5/2 15:32:16
//************************************************ */
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <cmath>
#include <stdlib.h>
using namespace std;
const int N=2005;
int n,l,v,link[N];
bool vis[N];
vector<int>eg[N];
bool dfs(int u)
{
    for(int i=eg[u].size()-1; i>=0; i--)
    {
        int to=eg[u][i];
        if(!vis[to])
        {
            vis[to]=1;
            if(link[to]==-1||dfs(link[to]))
            {
                link[to]=u;
                return 1;
            }
        }
    }
    return 0;
}
int main()
{
    //freopen("in.txt","r",stdin);
    scanf("%d",&n);
    for(int i=0; i<n; i++)
    {
        scanf("%d",&l);
        for(int j=0; j<l; j++)
        {
            scanf("%d",&v);
            eg[i].push_back(v+n);
        }
    }
    memset(link,-1,sizeof(link));
    int cnt=0;
    for(int i=0; i<n; i++)
    {
        memset(vis,0,sizeof(vis));
        if(dfs(i)) cnt++;
    }
    printf("%d\n",n-cnt);
    return 0;
}