BZOJ2215: [Poi2011]Conspiracy

BZOJ2215: [Poi2011]Conspiracy

https://lydsy.com/JudgeOnline/problem.php?id=3832

分析:

  • 这题好题啊。
  • 由观察得,假设有一个合法方案想要变成另一个合法方案。这个合法方案可以用\(2sat\)求。
  • 不能同时将\(2\)个或以上的同类型人换到对面去。
  • 因此枚举所有情况判断是否能换过去。
  • \(S\)为完全图集合,\(T\)为独立集合。
  • 考虑:
    1. \(S\)换一个到\(T\)
    1. \(T\)换一个到\(S\)
    1. \(S\)\(T\)互换一个。

代码:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <vector>
using namespace std;
#define N 10050
template <typename T> void chkmax(T &x,T y) {if(x<y) x=y;}
template <typename T> void chkmin(T &x,T y) {if(y<x) x=y;}
int n;
bool G[N][N],g[N>>1][N>>1];
int dfn[N],low[N],S[N],ins[N],scc,bl[N],ln,fa[N],tp;
int tot[N],h[N];
void tarjan(int x) {
	int i;
	dfn[x]=low[x]=++dfn[0]; S[++tp]=x; ins[x]=1;
	for(i=1;i<=ln;i++) if(G[x][i]) {
		if(!dfn[i]) {
			tarjan(i);
			chkmin(low[x],low[i]);
		}else if(ins[i]) chkmin(low[x],dfn[i]);
	}
	if(dfn[x]==low[x]) {
		scc++; int t=0;
		while(t!=x) {
			t=S[tp--]; ins[t]=0; bl[t]=scc;
		}
	}
}
int main() {
	scanf("%d",&n); ln=n<<1;
	int i,x,y;
	for(i=1;i<=n;i++) {
		scanf("%d",&x);while(x--)scanf("%d",&y),g[i][y]=1;
	}
	int j;
	for(i=1;i<=n;i++) {
		for(j=i+1;j<=n;j++) {
			if(g[i][j]) {
				G[i+n][j]=1;
				G[j+n][i]=1;
			}else {
				G[i][j+n]=1;
				G[j][i+n]=1;
			}
		}
	}
	for(i=1;i<=ln;i++) if(!dfn[i]) tarjan(i);
	for(i=1;i<=n;i++) {
		if(bl[i]==bl[i+n]) {
			puts("0"); return 0;
		}
		fa[i]=bl[i]>bl[i+n];
	}
	int ns=0,nt=0;
	for(i=1;i<=n;i++) {
		if(!fa[i]) ns++;
		else nt++;
	}
	int ans=ns&&nt;
	for(i=1;i<=n;i++) {
		for(j=1;j<=n;j++) {
			if(g[i][j]&&fa[i]!=fa[j]) {
				tot[i]++;
				h[i]=j;
			}
		}
		if(!fa[i]) {
			if(tot[i]==0&&ns>1) ans++;
		}else {
			if(tot[i]==ns&&nt>1) ans++;
			else {
				for(j=1;j<=n;j++) if(!g[i][j]&&fa[i]!=fa[j]) {h[i]=j; break;}
			}
		}
	}
	for(i=1;i<=n;i++) if(fa[i]==0) {
		for(j=1;j<=n;j++) if(fa[j]==1) {
			if((tot[i]==0|| (tot[i]==1&&h[i]==j) ) && ((tot[j]==ns|| (tot[j]==ns-1&&h[j]==i)) ) )ans++;
		}
	}
	printf("%d\n",ans);
}
posted @ 2019-01-01 17:05  fcwww  阅读(117)  评论(0编辑  收藏  举报