【bzoj3175】 TJOI2013攻击装置 二分图最大独立集

比较裸的二分图最大独立集,不过复杂度是不对的,匈牙利算法跑得太快了,然后要注意为了不超时,每次匈牙利的时候不能清空vis的数组,而是把它进行标记。


#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<iostream>
#include<algorithm>
#define maxn 40010
#define maxm 8*40010

using namespace std;

int head[maxn],next[maxm],to[maxm];
int lk[maxn];
int a[210][210];
int dx[4]={1,1,2,2};
int dy[4]={2,-2,1,-1};
int n,m,num,cnt,ans,T;
int vis[maxn];
char s[210];

bool find(int x)
{
	for (int p=head[x];p;p=next[p])
	  if (vis[to[p]]!=T)
	  {
	  	vis[to[p]]=T;
	  	if (!lk[to[p]] || find(lk[to[p]]))
	  	{
	  		lk[to[p]]=x;
	  		return 1;
	  	}
	  }
	return 0;
}

void addedge(int x,int y)
{
	num++;to[num]=y;next[num]=head[x];head[x]=num;
}

int main()
{
	scanf("%d",&n);
	for (int i=1;i<=n;i++)
	{
		scanf("%s",s+1);
	    for (int j=1;j<=n;j++)
	    {
	       if (s[j]=='0') a[i][j]=++cnt;
	       else a[i][j]=0;
	    }
    }
	for (int i=1;i<=n;i++)
	  for (int j=1;j<=n;j++)
	    if (a[i][j])
	    {
	    	for (int k=0;k<4;k++)
	    	{
	    		int x=i+dx[k],y=j+dy[k];
	    		if (x<1 || x>n || y<1 || y>n) continue;
	    		if (a[x][y]) addedge(a[i][j],a[x][y]),addedge(a[x][y],a[i][j]);
	    	}
	    }
	for (int i=1;i<=cnt;i++)
	{
		T++;
		if (find(i)) ans++;
	}
	printf("%d\n",cnt-ans/2);
	return 0;
}


你可能感兴趣的:(【bzoj3175】 TJOI2013攻击装置 二分图最大独立集)