[国家集训队]部落战争

Posted liguanlin1124

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[国家集训队]部落战争相关的知识,希望对你有一定的参考价值。

题目大意:给出n*m的矩阵以及r,c。求最小路径覆盖。

本来是匈牙利算法裸题,网络流也可以跑一跑。

但是我先粘一个骗分大错解:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int n,m,r,c,a[55],ans;
char mp[55][55];
int use[55][55],cov[55][55];
int main()
{
//    freopen("legion.in","r",stdin);
//    freopen("legion.out","w",stdout);
    scanf("%d%d%d%d",&n,&m,&r,&c);
    for(int i=1;i<=n;i++)
    {
        scanf("%s",mp[i]+1);
        for(int j=1;j<=m;j++)
        {
            a[i]+=(mp[i][j]==.);
            if(mp[i][j]==x)use[i][j]=1;
        }
        ans+=a[i];
    }
    for(int i=1;i<=n;i++)
    {
        if(i>r)
        {
            for(int j=1;j<=m;j++)
            {
                if(mp[i][j]==x)continue;
                if(j>c&&use[i-r][j-c]==0)
                {
                    use[i-r][j-c]=1;
                    cov[i][j]=1;
                    ans--;
                }else if(j+c<=m&&use[i-r][j+c]==0)
                {
                    use[i-r][j+c]=1;
                    cov[i][j]=1;
                    ans--;
                }
            }
        }
        if(r!=c&&i>c)
        {
            for(int j=1;j<=m;j++)
            {
                if(cov[i][j])continue;
                if(mp[i][j]==x)continue;
                if(j>r&&use[i-c][j-r]==0)
                {
                    use[i-c][j-r]=1;
                    cov[i][j]=1;
                    ans--;
                }else if(j+r<=m&&use[i-c][j+r]==0)
                {
                    use[i-c][j+r]=1;
                    cov[i][j]=1;
                    ans--;
                }
            }
        }
    }
    printf("%d
",ans);
    fclose(stdin);
    fclose(stdout);
    return 0;
}

这是我考试时写的(因为没好好听匈牙利算法和网络流),但是无脑骗了60?

放到某谷上面测70?

恕我直言在座的数据都很强 

接下来是整解:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define N 55
int n,m,r,c,hed[N*N],cnt;
char mp[N][N];
struct EG
{
    int to,nxt;
}e[4*N*N];
void ae(int f,int t)
{
    e[++cnt].to = t;
    e[cnt].nxt = hed[f];
    hed[f] = cnt;
}
int tn(int x,int y){return (x-1)*m+y;}
int dx[4],dy[4],fa[N*N];
bool vis[N*N];
int dfs(int x)//Hungary
{
    vis[x]=1;
    for(int j=hed[x];j;j=e[j].nxt)
    {
        int to = e[j].to;
        if(!vis[to])
        {
            vis[to]=1;
            if(!fa[to]||dfs(fa[to]))
            {
                fa[to]=x;
                return 1;
            }
        }
    }
    return 0;
}
int main()
{
//    freopen("legion.in","r",stdin);
//    freopen("legion.out","w",stdout);
    scanf("%d%d%d%d",&n,&m,&r,&c);
    dx[0]=dx[1]=dy[2]=r,dx[2]=dx[3]=dy[0]=c,dy[1]=-c,dy[3]=-r;
    for(int i=1;i<=n;i++)
        scanf("%s",mp[i]+1);
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            if(mp[i][j]==.)
            {
                for(int k=0;k<4;k++)
                {
                    int x = i+dx[k],y = j+dy[k];
                    if(x<=0||y<=0||x>n||y>m)continue;
                    if(mp[x][y]==.)
                        ae(tn(i,j),tn(x,y));
                }
            }
        }
    }
    int ans  =0;
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            if(mp[i][j]==.)
            {
                memset(vis,0,sizeof(vis));
                ans+=(dfs(tn(i,j))==0);
            }
        }
    }
    printf("%d
",ans);
    return 0;
}

 

以上是关于[国家集训队]部落战争的主要内容,如果未能解决你的问题,请参考以下文章

clash royale怎么换中文 部落冲突皇室战争中文设置

[Bzoj ]2150 部落战争

bzoj2150: 部落战争(匈牙利)

bzoj2150: 部落战争

部落战争(建图+最小路径覆盖)

bzoj2150部落战争 有上下界最小流