【TJOI & HEOI 2016】【BZOJ 4554】【JZOJ 4612】 游戏

来源:互联网 发布:红包尾数控制软件 编辑:程序博客网 时间:2024/06/07 06:36

Description

这里写图片描述
这里写图片描述

Analysis

二分图匹配。
由于本人之前中了网络流的毒,此题便乱搞搞出来了。
首先,对于网络流的知识,可以参考专题“网络流与线性规划”
这题,就是最大点独立集。
但是不是裸的,因为有”#”影响一行情况。
所以,一行或一列中,被”#”隔开的部分视为不同的行或列。

Code

#include<cstdio>#include<algorithm>#define fo(i,a,b) for(int i=a;i<=b;i++) using namespace std;const int N=53,M=5105;int n,m,st,x[N][N],y[N][N];int pos[M],bz[M],a[M][M];bool p[M];char map[N][N];void link(int u,int v){    a[u][++a[u][0]]=v;}bool match(int v){    if(bz[v]==st) return 0;    bz[v]=st;    fo(i,1,a[v][0])    {        int u=a[v][i];        if(!pos[u] || match(pos[u]))        {            pos[u]=v;            return 1;        }    }    return 0;}int main(){    scanf("%d %d\n",&n,&m);    fo(i,1,n)    {        fo(j,1,m) scanf("%c",&map[i][j]);        scanf("\n");    }    int xx=0,yy=0;    fo(i,1,n)    {        xx++;        fo(j,1,m)        {            if(map[i][j]=='#') xx++;            if(map[i][j]=='*') x[i][j]=xx;        }    }    fo(j,1,m)    {        yy++;        fo(i,1,n)        {            if(map[i][j]=='#') yy++;            if(map[i][j]=='*') y[i][j]=yy;        }    }    int mx=0;    fo(i,1,n)        fo(j,1,m)            if(map[i][j]=='*')            {                link(x[i][j],xx+y[i][j]);                p[x[i][j]]=p[xx+y[i][j]]=1;                mx=max(mx,xx+y[i][j]);            }    int tot=0,t=0;    fo(i,1,mx)        if(p[i]) tot++;    for(st=1;st<=mx;st++)        if(match(st)) t++;    printf("%d",t);    return 0;}
0 0
原创粉丝点击