【最小顶点覆盖】POJ 2226

来源:互联网 发布:python os.environ 编辑:程序博客网 时间:2024/04/29 18:48

这题跟POJ 3041有点区别,这里不是一整行一整行地消灭,是某几个连续的格子一起消灭,因此构图的时候要注意,从上到下把每行连续的从1开始标号,作为左集合,从左到右把每列连续的从1开始编号,作为右集合,接着就匈牙利算法求最大匹配数=最小顶点覆盖数,这里有点诡异,左右集合各自的编号数最大竟然多于50*50,要把数组开大点

#include <map>#include <set>#include <list>#include <queue>#include <deque>#include <stack>#include <string>#include <cstdio>#include <math.h>#include <iomanip>#include <cstdlib>#include <limits.h>#include <string.h>#include <iostream>#include <fstream>#include <algorithm>using namespace std;#define LL long long#define MIN -99999999#define MAX 99999999#define pii pair<int ,int>#define bug cout<<"here!!"<<endl#define PI acos(-1.0)#define FRE freopen("input.txt","r",stdin)#define FF freopen("output.txt","w",stdout)#define eps 1e-8#define N 55char str[N][N];int g[N][N];bool vis[1001];int mat[1001];int n,m;int re[1001][1001];int xx,yy;bool sear(int s){    int i,j;    for(i=1;i<=yy;i++){        if(re[s][i] && !vis[i]){            vis[i]=1;            if(mat[i]==0 || sear(mat[i])){                mat[i] = s;                return true;            }        }    }    return false;}//建图void gao(){    int i,j;    int k=0;    //找行连续的    for(i=1;i<=n;i++){        for(j=1;j<=m;){            if(g[i][j]){                k++;                while(j<=m && g[i][j]){                    g[i][j++] = k;                }            } else j++;        }    }    xx = k;    k = 0;    //找列连续的    for(j=1;j<=m;j++){        for(i=1;i<=n;){            if(g[i][j]){                k++;                while(i<=n && g[i][j]){                    re[g[i][j]][k] = 1;                    i++;                }            } else i++;        }    }    yy = k;}int main(){    int i,j;    while(scanf("%d%d",&n,&m) !=-1){        for(i=1;i<=n;i++){            scanf("%s",str[i]+1);        }        memset(g,0,sizeof(g));        for(i=1;i<=n;i++){            for(j=1;j<=m;j++){                if(str[i][j]=='*'){                    g[i][j] = 1;                }            }        }        memset(re,0,sizeof(re));        gao();        int cnt=0;        memset(mat,0,sizeof(mat));        for(i=1;i<=xx;i++){            memset(vis,0,sizeof(vis));            if(sear(i))cnt++;        }        cout<<cnt<<endl;    }    return 0;}


原创粉丝点击