Luogu P3513 [POI2011]KON-Conspiracy
分析
把图E分成A和B,其中A是子团,B是独立集
显然想到2-set,把一个点裂成两个,分别表示在A和在B
但2-set只能判断是否存在解,不能判断解的数量
所以观察发现:如果想产生新的解,必然是A,B间发生1个点的变化(反证)
所以,分类
- A给B点u,则要满足u与B无连点
- B给A点v,则v与A无不连点
- A,B交换(u,v),则u与B最多有连点v,v与A最多有不连点u
所以用b数组记录A中每个点与B的连点个数和编号,B中每个点与A的不连点个数和编号即可
其中2-set判解是通过tarjan缩点判是否有在A的状态和在B的状态在一个SCC中,有则无解,反之无
构造一组解,可以想缩点后建反图拓扑排序,而SCC的标号是反拓扑序,所以直接判co[i]即可
#include<bits/stdc++.h>
using namespace std;
inline int rd() {
char ch=getchar(); int ret=0;
while(ch<'0'||ch>'9') ch=getchar();
while(ch>='0'&&ch<='9') {
ret=(ret<<1)+(ret<<3)+ch-'0';
ch=getchar();
}
return ret;
}
const int N=10005,M=5005*5005;
int to[M],nxt[M],cnt,n,he[N],low[N],dfn[N],st[N],top,co[N],col,b[N],fl[N];
bool a[5005][5005];
inline void add(int u,int v) {
to[++cnt]=v,nxt[cnt]=he[u],he[u]=cnt;
}
void tar(int u) {
low[u]=dfn[u]=++cnt; st[++top]=u;
for(int e=he[u];e;e=nxt[e]) {
int v=to[e];
if(!dfn[v]) {
tar(v),low[u]=min(low[v],low[u]);
} else if(!co[v]) low[u]=min(low[u],dfn[v]);
}
if(low[u]==dfn[u]) {
col++;
co[u]=col;
while(st[top]!=u) {
co[st[top]]=col; top--;
}
top--;
}
}
int main() {
freopen("conspiracy.in","r",stdin);
freopen("conspiracy.out","w",stdout);
n=rd();
for(int i=1;i<=n;i++) {
int k=rd();
while(k--){
a[i][rd()]=1;
}
}
for(int i=1;i<=n;i++) {
for(int j=1;j<i;j++) {
if(a[i][j]) {
add(i+n,j),add(j+n,i);
} else {
add(i,j+n),add(j,i+n);
}
}
}
cnt=0;
for(int i=1;i<=n+n;i++) {
if(!dfn[i]) tar(i);
}
for(int i=1;i<=n;i++) {
if(co[i]==co[i+n]) {
puts("0"); return 0;
}
}
int Sa=0,Sb=0;
for(int i=1;i<=n;i++) {
fl[i]=co[i]>co[i+n];
if(fl[i]) Sb++; else Sa++;
}
for(int i=1;i<=n;i++) {
if(!fl[i]) {
for(int j=1;j<=n;j++) {
if(fl[j]&&a[i][j]) {
if(!b[i]) b[i]=j;
else b[i]=-1;
}
}
} else {
for(int j=1;j<=n;j++) {
if(!fl[j]&&!a[i][j]) {
if(!b[i]) b[i]=j;
else b[i]=-1;
}
}
}
}
int ans=0;
if(Sa&&Sb) ans++;
for(int i=1;i<=n;i++) {
if(!b[i]) {
if(fl[i]&&Sb>1) ans++;
if(!fl[i]&&Sa>1) ans++;
}
}
if(Sa&&Sb) {
for(int i=1;i<=n;i++) {
for(int j=1;j<i;j++) {
if(fl[i]^fl[j]&&(b[i]==j||b[i]==0)&&(b[j]==i||b[j]==0)) {
ans++;
}
}
}
}
printf("%d\n",ans);
return 0;
}

2-set,性质
浙公网安备 33010602011771号