• P3355 骑士共存问题 题解


    Link

    P3355 骑士共存问题

    Solve

    对棋盘进行染色,黑白节点分别作为二分图的左右部节点。

    对于一个在白色节点的马来说,一定在一步之内不能跳到另外一个白色节点

    则通过"日"在相对应的节点之间建边

    求上述二分图的的最大独立子集就是答案

    Code

    #include <cstdio>
    #include <iostream>
    #include <cstring>
    #include <vector>
    using namespace std;
    const int MAXN = 1000000;
    const int nxt_x[8]={-1,-2,-2,-1,1,2,2,1};
    const int nxt_y[8]={-2,-1,1,2,2,1,-1,-2};
    int n,m,cnt,ans;
    bool Map[2001][2001];
    bool used[100001];
    int match[100001],head[MAXN];
    vector<int> node;
    struct Edge
    {
        int next,to;
    }e[MAXN];
    inline void add(int u,int v)
    {
        cnt++;
        e[cnt].to=v;
        e[cnt].next=head[u];
        head[u]=cnt;
    }
    bool Find(int u)
    {
        for(int i=head[u];i;i=e[i].next)
        {
            int v=e[i].to;
            if(!used[v])
            {
                used[v]=1;
                if(match[v]==-1 || Find(match[v]))
                {
                    match[v]=u;
                    return 1;
                }
            }
        }
        return 0;
    }
    int main()
    {
    	freopen("P3355.in","r",stdin);
    	freopen("P3355.out","w",stdout); 
        cin>>n>>m;
        for(int i=1;i<=m;i++)
        {
            int x,y;
            cin>>x>>y;
            Map[x][y]=1;
        }
        for(int x=1;x<=n;x++)
            for(int y=1;y<=n;y++)
                if(!Map[x][y] && (x+y)%2)
                {
                	node.push_back(n*(x-1)+y);
                    for(int i=0;i<8;i++)
                    {
                        int to_x=x+nxt_x[i];
                        int to_y=y+nxt_y[i];
                        if(to_x<1 || to_x>n || to_y<1 || to_y>n) continue;
                        if(!Map[to_x][to_y])
                            add(n*(x-1)+y,n*(to_x-1)+to_y);
                    }	
                }
        memset(match,-1,sizeof(match));
        for(int i=0;i<node.size();i++)
        {
            memset(used,0,sizeof(used));
            ans+=Find(node[i]);
        }
        cout<<n*n-m-ans;
        return 0;
    }
    
  • 相关阅读:
    美多商城项目(一)
    Linux安装Qt
    mysql之初体验
    Linux系统编程目录
    Linux 多线程
    进程间通信
    Linux进程
    Linux文件IO(简易)
    Linux常用基本操作
    重绘
  • 原文地址:https://www.cnblogs.com/martian148/p/13918009.html
Copyright © 2020-2023  润新知