标签:2-sat,平面图
题目
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 HINT
Source
Day1
分析
平面图的定理:$m<=3*n-6$
可以用这个剪枝
反正用2-sat乱搞了啊qwq
code
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<algorithm>
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define dep(i,a,b) for(int i=a;i>=b;i--)
#define ll long long
#define mem(x,num) memset(x,num,sizeof x)
#define reg(x) for(int i=last[x];i;i=e[i].next)
using namespace std;
inline ll read()
{
ll f=1,x=0;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
const int maxn=1e5+6;
int u[maxn],v[maxn],c[maxn],pos[maxn],last[maxn],que[maxn],belong[maxn];
int cnt=1,n,m,low[maxn],dfn[maxn],ind,top,scc,Que;
bool inq[maxn];
struct edge{int to,next;}e[maxn<<2];
void insert(int u,int v){e[++cnt]=(edge){v,last[u]};last[u]=cnt;}
void tarjan(int x){
low[x]=dfn[x]=++ind;
inq[x]=1;que[++top]=x;
reg(x)
if(!dfn[e[i].to])tarjan(e[i].to),low[x]=min(low[x],low[e[i].to]);
else if(inq[e[i].to])low[x]=min(low[x],dfn[e[i].to]);
if(low[x]==dfn[x]){
scc++;
int now=-1;
while(now!=x){
now=que[top--];inq[now]=0;
belong[now]=scc;
}
}
}
bool jud()
{
rep(i,1,m)
if(belong[2*i]==belong[2*i-1])return 0;
return 1;
}
int main()
{
Que=read();
while(Que--){
n=read(),m=read();
rep(i,1,m)u[i]=read(),v[i]=read();
mem(last,0);cnt=1;scc=ind=0;
mem(low,0);mem(dfn,0);
rep(i,1,n)c[i]=read();
if(m>3*n-6){puts("NO");continue;}
rep(i,1,n)pos[c[i]]=i;
top=0;
rep(i,1,m){
v[i]=pos[v[i]];u[i]=pos[u[i]];
if(u[i]>v[i])swap(u[i],v[i]);
if(v[i]-u[i]==1||(v[i]==n&&u[i]==1))continue;
u[++top]=u[i],v[top]=v[i];
}
m=top;
rep(i,1,m)
rep(j,i+1,m)
if((u[i]<u[j]&&u[j]<v[i]&&v[i]<v[j])||(u[j]<u[i]&&u[i]<v[j]&&v[j]<v[i]))
{
insert(2*i-1,2*j);
insert(2*i,2*j-1);
insert(2*j-1,2*i);
insert(2*j,2*i-1);
}
top=0;
rep(i,1,2*m)
if(!dfn[i])tarjan(i);
if(jud())puts("YES");
else puts("NO");
}
return 0;
}