wikioi 1922 骑士共存问题 最大独立集

题目描述 Description

在一个n*n个方格的国际象棋棋盘上,马(骑士)可以攻击的棋盘方格如图所示。棋盘
上某些方格设置了障碍,骑士不得进入。

 《wikioi 1922 骑士共存问题 最大独立集》

对于给定的n*n个方格的国际象棋棋盘和障碍标志,计算棋盘上最多可以放置多少个骑
士,使得它们彼此互不攻击。

输入描述 Input Description

第一行有2 个正整数n 和m (1<=n<=200, 0<=m<n^2),
分别表示棋盘的大小和障碍数。接下来的m 行给出障碍的位置。每行2 个正整数,表示障
碍的方格坐标。

输出描述 Output Description

将计算出的共存骑士数输出

样例输入 Sample Input

3 2

1 1

3 3

样例输出 Sample Output

5

最大独立集=点数-最大匹配数(这题外加障碍数),黑书上讲的很明白了

单组数据测试的话可以用匈牙利算法,多组数据就必须用网络流来求最大匹配了

#include <cstdlib>
#include <cctype>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <vector>
#include <string>
#include <iostream>
#include <sstream>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <fstream>
#include <numeric>
#include <iomanip>
#include <bitset>
#include <list>
#include <stdexcept>
#include <functional>
#include <utility>
#include <ctime>

using namespace std;

#define PB push_back
#define MP make_pair
#define CLR(vis) memset(vis,0,sizeof(vis))
#define MST(vis,pos) memset(vis,pos,sizeof(vis))
#define MAX3(a,b,c) max(a,max(b,c))
#define MAX4(a,b,c,d) max(max(a,b),max(c,d))
#define MIN3(a,b,c) min(a,min(b,c))
#define MIN4(a,b,c,d) min(min(a,b),min(c,d))
#define PI acos(-1.0)
#define INF 0x7FFFFFFF
#define LINF 1000000000000000000LL
#define eps 1e-8

typedef long long ll;
typedef unsigned long long ull;

const int dx[10]={1,1,2,2,-1,-1,-2,-2};
const int dy[10]={2,-2,1,-1,2,-2,1,-1};
int n,m;
int mp[222][222],col[40010];
int link[40010],vis[40010];
int t;

int dfs(int i,int j)
{
    int x,y;
    for(int k=0;k<8;k++)
    {
        x=i+dx[k];
        y=j+dy[k];
        if(x<1 || y<1 || x>n || y>n || mp[x][y] || vis[(x-1)*n+y]==t)
            continue;
        vis[(x-1)*n+y]=t;
        int ii,jj;
        if(link[(x-1)*n+y]%n==0)
            ii=link[(x-1)*n+y]/n,jj=n;
        else
            ii=(link[(x-1)*n+y]/n)+1,jj=link[(x-1)*n+y]%n;

        if(!link[(x-1)*n+y] || dfs(ii,jj) )
		{
			link[(x-1)*n+y]=(i-1)*n+j;
			return 1;
		}
    }
    return 0;
}

int main()
{
    cin>>n>>m;
    int x,y;
    memset(mp,0,sizeof(mp));
    for(int i=0;i<m;i++)
    {
        scanf("%d%d",&x,&y);
        mp[x][y]=1;
    }
    int sum=n*n;
    int tmp=0;
    for(int i=1;i<=sum;i++)
    {
        col[i]=tmp;
        tmp^=1;
        if( !(n&1) && !(i%n))
		{
			tmp^=1;
		}
    }
    int ans=0;
    memset(link,0,sizeof(link));
    memset(vis,0,sizeof(vis));
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n;j++)
        {
            if(mp[i][j])
                continue;
            t=(i-1)*n+j;
            if(col[t])
                continue;
            if(dfs(i,j))
                ans++;
        }
    }
    cout<<sum-(ans+m)<<endl;

    return 0;
}

    原文作者:骑士周游问题
    原文地址: https://blog.csdn.net/budlele/article/details/38470897
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞