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

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

 

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

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

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

3 2

1 1

3 3

5


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

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


#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

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



你可能感兴趣的:(图论)