poj-3041【二分图最小顶点覆盖】

来源:互联网 发布:上搜狐知天下 编辑:程序博客网 时间:2024/05/16 06:00

自从看了二分图之后,感觉好多题目的解题方法真的跟以往的思维方式不一样了。。。。这可能就是抽象思维吧。

这个题目的意思是在网格中有k个小行星,你的炮弹只能一次只能摧毁一行或者一列的小行星,让你用求出最小的炮弹数目来毁掉这些小行星。

这个题目抽象的地方在炮弹当做顶点把小行星当做边,把发射的光束当做顶点,然后建图。。。。这样建出图之后求这个二分图的最大匹配,因为对于二分图来说,

最小顶点覆盖=最大匹配,求出最大匹配数来就是对应的最小顶点覆盖数。

#include <cstring>#include <cstdio>#include <iostream>#include <algorithm>#include <queue>#include <string>#include <cmath>#define maxn 1010#define Max 0x3f3f3f3fusing namespace std;int n,m;vector<int>G[maxn];bool update[maxn];void add(int s,int t){    G[s].push_back(t);    G[t].push_back(s);}int match[maxn];void Init(){    for (int i=1;i<=2*n;i++)    {        G[i].clear();    }}bool  Dfs(int now){    update[now]=true;    for (int i=0;i<G[now].size();i++)    {        int t=G[now][i];        if (match[t]==-1||(!update[match[t]]&&Dfs(match[t])))//??????????????        {            match[now]=t;            match[t]=now;            return true;        }    }    return false;}void Get(){    int res=0;    memset(match,-1,sizeof(match));    for (int i=1;i<=2*n;i++)    {        if (match[i]==-1)        {            fill(update+1,update+2*n+1,false);            if (Dfs(i))            {                res++;            }        }    }    cout<<res<<endl;}int main(){    int a,b;    while(scanf("%d %d",&n,&m)!=EOF)    {        Init();        while(m--)        {            scanf("%d %d",&a,&b);            add(a,b+n);        }        Get();    }    return 0;}


0 0
原创粉丝点击