BZOJ.1997.[HNOI2010]Planar(2-SAT)

Posted SovietPower

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BZOJ.1997.[HNOI2010]Planar(2-SAT)相关的知识,希望对你有一定的参考价值。

题目链接

存在一个环,说明什么?
画了一下样例二,直接是个环;然后重新画了下样例一,可以画成一个环,非环上的边可以连在环内或环外
这些非环上的边不能相交。然后就成了POJ3207原题了,只是圆上排列顺序不同。
不过边数很多,必须利用平面图的性质: 平面图的边数小于等于3n-6,来将边数降到O(n)级别

当然这种并查集也能做。。
莫名跑的慢

#include <cstdio>
#include <cctype>
#include <cstring>
#include <algorithm>
//#define gc() getchar()
#define gc() (SS==TT&&(TT=(SS=IN)+fread(IN,1,MAXIN,stdin),SS==TT)?EOF:*SS++)
const int N=20005,M=4e5+5,MAXIN=2e6;

int n,m,A[N]/*规定一个数在圆上的位置*/,st[N],ed[N],Enum,H[N],nxt[M],to[M];
int sk[N],top,cnt,bel[N],id,dfn[N],low[N];
bool ins[N],isc[N];
char IN[MAXIN],*SS=IN,*TT=IN;

inline int read()
{
	int now=0;register char c=gc();
	for(;!isdigit(c);c=gc());
	for(;isdigit(c);now=now*10+c-\'0\',c=gc());
	return now;
}
inline void AddEdge(int u,int v){
	to[++Enum]=v, nxt[Enum]=H[u], H[u]=Enum;
}
void Tarjan(int x)
{
	dfn[x]=low[x]=++id, sk[++top]=x, ins[x]=1;
	for(int v,i=H[x]; i; i=nxt[i])
		if(!dfn[v=to[i]]) Tarjan(v),low[x]=std::min(low[x],low[v]);
		else if(ins[v]) low[x]=std::min(low[x],dfn[v]);
	if(low[x]==dfn[x])
	{
		++cnt;
		do{
			bel[sk[top]]=cnt, ins[sk[top--]]=0;
		}while(x!=sk[top+1]);
	}
}

int main()
{
	int t=read();
	while(t--)
	{
		n=read(),m=read();
		for(int i=1; i<=m; ++i) st[i]=read(),ed[i]=read();
		for(int i=1; i<=n; ++i) A[read()]=i;
		if(m>3*n-6) {puts("NO"); continue;}
		cnt=Enum=id=0, memset(H,0,sizeof H);
		memset(isc,0,sizeof isc), memset(dfn,0,sizeof dfn);
		for(int i=1; i<=m; ++i)
			if(A[st[i]]>A[ed[i]]) st[i]=A[st[i]],ed[i]=A[ed[i]],std::swap(st[i],ed[i]);
			else st[i]=A[st[i]],ed[i]=A[ed[i]];
		for(int i=1; i<=m; ++i)
			if(st[i]+1==ed[i]||(st[i]==1&&ed[i]==n)) isc[i]=isc[i+m]=1;
		for(int i=1; i<=m; ++i)
			if(!isc[i]) for(int j=1; j<=m; ++j)
					if(!isc[j] && i!=j && st[j]<st[i]&&st[i]<ed[j]&&ed[j]<ed[i])
						AddEdge(i,j+m),AddEdge(i+m,j),AddEdge(j,i+m),AddEdge(j+m,i);
		for(int i=1; i<=m<<1; ++i)//是枚举两个集合的边。。
			if(!isc[i] && !dfn[i]) Tarjan(i);
		bool f=1;
		for(int i=1; i<=m; ++i)
			if(!isc[i] && bel[i]==bel[i+m]) {f=0; break;}
		puts(f?"YES":"NO");
	}
	return 0;
}

以上是关于BZOJ.1997.[HNOI2010]Planar(2-SAT)的主要内容,如果未能解决你的问题,请参考以下文章

BZOJ1997[Hnoi2010]Planar 2-SAT

bzoj 1997: [Hnoi2010]Planar

BZOJ 1997[Hnoi2010]Planar

bzoj 1997: [Hnoi2010]Planar

bzoj1997 [Hnoi2010]Planar

bzoj1997: [Hnoi2010]Planar