[POJ]1422-Air Raid(最小路径覆盖)

来源:互联网 发布:淘宝网信用评价体系 编辑:程序博客网 时间:2024/05/16 15:31

一道匹配的水题,关键在于 节点数-最大匹配数=最小路径覆盖最小路径覆盖指,假如选了一个边就相当于覆盖了该边的两个端点,你需要选择最少的边来覆盖所有的点。

这道题是典型的最小路径覆盖问题,有向图可以理解为一个二分图,该二分图中有两个集合M,N。M和N的顶点和有向图的顶点一致,即M=V,N=V。如果存在一条路径P,由a->b。则在二分图中,存在一条路,Ma--Nb。在程序实现时和一般无向图没有什么大的区别,不需要多余的操作,只是从改变上要理解。值得一提的是,虽然顶点数题目中给的范围是<=120,但我把数组从125改到155就是WA和AC的区别。=.= 坑爹啊~


#include<iostream>#define MAXV 150using namespace std;int match[MAXV+5];bool visited[MAXV],map[MAXV+5][MAXV+5];int V,E;bool pathfind(int s){    for(int i=1;i<=V;i++)    {        if(!visited[i]&&map[s][i])        {            visited[i]=1;            if(match[i]==0||pathfind(match[i]))            {                match[i]=s;                return true;            }        }    }    return false;}int maxmatch(){    int ans=0;    memset(match,0,sizeof(match));    for(int i=1;i<=V;i++)    {        memset(visited,0,sizeof(visited));        if(pathfind(i)) ans++;    }    return ans;}bool init(){    memset(map,0,sizeof(map));    cin>>V>>E;    for(int i=1;i<=E;i++)    {        int a,b;        cin>>a>>b;        map[a][b]=1;    }    return true;}int main(){    int cas;    cin>>cas;    while(cas--)    {        init();        cout<<V-maxmatch()<<endl;    }    return 0;}

原创粉丝点击