【bzoj2744】[HEOI2012]朋友圈 二分图匹配

算是一道好题了吧,竟然自己想出来了。

首先如果是一般图的最大团,那么肯定是不可做,所以这道题的条件一定有什么性质。

仔细一看,对于A国,我们分成奇数和偶数两类点,我们发现边全都是在两类点之间的,同类点之间没有边。

这不是一个二分图嘛?二分图的最大团?嘿嘿嘿,最大为2吧。

再看B国,同样的做法,但是我们发现同类点之间两两有边。

貌似有一个性质,二分图的最大独立集等于它补图的最大团(一般图适不适用呢?)。

我们发现B国的补图恰好是一个二分图,于是问题就解决了。

先枚举A国中选哪0、1、2个点,然后再挑出B国中同时与这几个点相连的点,建出补图,求最大独立集=总点数-最大匹配数。

注意:

貌似直接清零并不优美,所以从Po姐那里学习了一下时间戳,大概就是记录一下每个数组使用的时间吧。


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

using namespace std;

int b[maxn][maxn],head[maxn],to[maxm],next[maxm];
int A[maxn],B[maxn];
int tag[maxn],lk[maxn],tim[maxn];
int vis[maxn];
int na,nb,m,num,ans,T,T1,T2;

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

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

int Count(int x)
{
	int ans=0;
	for (int i=x;i;i-=(i&(-i))) ans++;
	return ans;
}

int solve()
{
	int ans=0;
	for (int i=1;i<=nb;i++)
	  if (tag[i]==T1)
	  {
	  	T2++;
	    if (find(i)) ans++;
	  }
	  else ans++;
	return nb-ans;
}

int main()
{
	T1=T2=ans=0;
	scanf("%d%d%d",&na,&nb,&m);
	for (int i=1;i<=na;i++) scanf("%d",&A[i]);
	for (int i=1;i<=nb;i++) scanf("%d",&B[i]);
	for (int i=1;i<=m;i++)
	{
		int x,y;
		scanf("%d%d",&x,&y);
		b[x][y]=1;
	}
	for (int i=1;i<=nb;i++)
	  if (B[i]&1)
		for (int j=1;j<=nb;j++)
		  if (!(B[j]&1))
		    if (!(Count(B[i]|B[j])&1)) addedge(i,j);
	ans=max(ans,solve());
	for (int i=1;i<=na;i++)
	{
		T1++;
		for (int j=1;j<=nb;j++)
		  if (b[i][j]) tag[j]=T1;
		ans=max(ans,solve()+1);
	}
	for (int i=1;i<=na;i++)
	  if (A[i]&1)
		for (int j=i+1;j<=na;j++)
		  if (!(A[i]&1))
		  {
		    T1++;
		    for (int k=1;k<=nb;k++)
		      	if (b[i][k] && b[j][k]) tag[k]=T1;
		    ans=max(ans,solve()+2);
		  }
	printf("%d\n",ans);
	return 0;
}


你可能感兴趣的:(【bzoj2744】[HEOI2012]朋友圈 二分图匹配)