POJ1422 SSL-1340 最小路径覆盖【二分图的最大匹配】

链接

http://poj.org/problem?id=1422

大意

t t 组数据,每组数据给定一个 n n 个点, m m 条边的有向图,求它的最小路径覆盖

思路

匈牙利算法
根据一个公式:
最小路径覆盖数=原图G的顶点数-二分图的最大匹配数

代码

#include
#include
#define N 121
#define M 10121
#define LL long long
#define r(i,a,b) for(int i=a;i<=b;i++)
#define zero(a) memset(a,0,sizeof(a))
using namespace std;
struct node{int next,to;}edge[M];int l[M],tot,x,y,n,m,q,link[N],ans,t;bool vis[N];
void add(int u,int v){edge[++tot].to=v;edge[tot].next=l[u];l[u]=tot;}
LL read()//输入流
{
    char c;int f=0,d=1;
    while((c=getchar())<48||c>57)if(c=='-')d=-1;f=(f<<3)+(f<<1)+c-48;
    while((c=getchar())>=48&&c<=57)f=(f<<3)+(f<<1)+c-48;
    return d*f;
}
bool find(int p)//匈牙利算法
{
    for(int i=l[p];i;i=edge[i].next)
     if(!vis[edge[i].to])
      {
        vis[edge[i].to]=1;
        q=link[edge[i].to];
        link[edge[i].to]=p;
        if(!q||find(q)) return true;
        link[edge[i].to]=q;
      }
    return false;
}
int main()
{
    t=read();
    while(t--)
    {
        tot=0;zero(l);zero(link);//初始化
        n=read();m=read();
        r(i,1,m) add(read(),read());ans=0;//输入+建图
        r(i,1,n)
        {
            zero(vis);
            ans+=find(i);//增广路
        }
        printf("%d\n",n-ans);//输出
    }
}

你可能感兴趣的:(GT,图的匹配问题)