zoukankan      html  css  js  c++  java
  • 【BZOJ1997】[Hnoi2010]Planar 2-SAT

    【BZOJ1997】[Hnoi2010]Planar

    Description

    Input

    Output

    Sample Input

    2
    6 9
    1 4
    1 5
    1 6
    2 4
    2 5
    2 6
    3 4
    3 5
    3 6
    1 4 2 5 3 6
    5 5
    1 2
    2 3
    3 4
    4 5
    5 1
    1 2 3 4 5

    Sample Output

    NO
    YES

    题解:跟POJ的某熊猫题一模一样?(然而我并没有写那题的题解~)

    本题可以理解为圆上有一些点之间要连线,这些线要么在圆里要么在圆外,问能否让所有的线都不相交。

    直接枚举出每对可能相交的线,然后一个在圆里另一个就必须在圆外,所以从A向B'连边,从B向A'连边就行了。

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    using namespace std;
    int n,m,T,cnt,tot,sum,top;
    int to[1000010],next[1000010],head[2010],dep[2010],low[2010],ins[2010],sta[2010],bel[2010];
    int p[2010],pa[20010],pb[20010];
    int rd()
    {
    	int ret=0,f=1;	char gc=getchar();
    	while(gc<'0'||gc>'9')	{if(gc=='-')f=-f;	gc=getchar();}
    	while(gc>='0'&&gc<='9')	ret=ret*10+gc-'0',gc=getchar();
    	return ret*f;
    }
    void tarjan(int x)
    {
    	dep[x]=low[x]=++tot,ins[x]=1,sta[++top]=x;
    	for(int i=head[x];i!=-1;i=next[i])
    	{
    		if(!dep[to[i]])	tarjan(to[i]),low[x]=min(low[x],low[to[i]]);
    		else	if(ins[to[i]])	low[x]=min(low[x],dep[to[i]]);
    	}
    	if(dep[x]==low[x])
    	{
    		int t;
    		sum++;
    		do
    		{
    			t=sta[top--],ins[t]=0,bel[t]=sum;
    		}while(t!=x);
    	}
    }
    void add(int a,int b)
    {
    	to[cnt]=b,next[cnt]=head[a],head[a]=cnt++;
    }
    void work()
    {
    	memset(head,-1,sizeof(head));
    	memset(dep,0,sizeof(dep));
    	n=rd(),m=rd(),cnt=tot=sum=0;
    	int i,j,a,b;
    	for(i=0;i<m;i++)	pa[i]=rd(),pb[i]=rd();
    	for(i=1;i<=n;i++)	p[rd()]=i;
    	if(m>3*n-6)
    	{
    		printf("NO
    ");
    		return ;
    	}
    	for(i=0;i<m;i++)
    	{
    		pa[i]=p[pa[i]],pb[i]=p[pb[i]];
    		if(pa[i]>pb[i])	swap(pa[i],pb[i]);
    		if(pa[i]+1==pb[i])	continue;
    		for(j=0;j<i;j++)
    		{
    			if(pa[j]+1==pb[j])	continue;
    			if((pa[j]>pa[i]&&pa[j]<pb[i]&&pb[j]>pb[i])||(pa[j]<pa[i]&&pb[j]>pa[i]&&pb[j]<pb[i]))
    				add(i<<1|1,j<<1),add(j<<1|1,i<<1),add(i<<1,j<<1|1),add(j<<1,i<<1|1);
    		}
    	}
    	for(i=0;i<2*m;i++)	if(!dep[i])	tarjan(i);
    	for(i=0;i<m;i++)	if(bel[i<<1]==bel[i<<1|1])
    	{
    		printf("NO
    ");
    		return ;
    	}
    	printf("YES
    ");
    	return ;
    }
    int main()
    {
    	T=rd();
    	while(T--)	work();
    	return 0;
    }
  • 相关阅读:
    iOS 远程推送
    iOS 本地推送
    iOS 循环利用的注意事项
    iOS 通知代理执行代理方式时,代理为nil的解决办法
    iOS SSZipArchive
    iOS PushMebaby
    Objective
    Objective
    Objective
    Objective
  • 原文地址:https://www.cnblogs.com/CQzhangyu/p/7044316.html
Copyright © 2011-2022 走看看