比赛 |
COGS快乐周赛 |
评测结果 |
AAAAAAAAAA |
题目名称 |
平面图判定 |
最终得分 |
100 |
用户昵称 |
瑆の時間~無盡輪迴·林蔭 |
运行时间 |
0.497 s |
代码语言 |
C++ |
内存使用 |
17.21 MiB |
提交时间 |
2020-01-10 18:02:53 |
显示代码纯文本
//按点在哈密顿回路上的顺序确定关系
//对3n-6上限的说明:回路本身n,内部n-3,外部n-3
//n-3:任选一个点,向除自己和旁边两点以外所有点各一条
//可以发现在按照上述方案后不可能出现新的内部边
#include<iostream>
#include<cstdio>
#include<vector>
#include<algorithm>
#include<cstring>
using namespace std;
int ex[40001],ey[40001],C[40001],X[40001],Y[40001];
bool cir[1001][1001];
vector<int>sat[40001];
int ID[40001],dfn[40001],low[40001],vis[40001],ls[40001],stack[40001];
int t,n,m,a1,a2,cnt,num,qlt,jl;
void init()
{
n=m=a1=a2=cnt=num=qlt=jl=0;
memset(ID,0,sizeof(ID));
memset(low,0,sizeof(low));
memset(dfn,0,sizeof(dfn));
memset(vis,0,sizeof(vis));
memset(ls,0,sizeof(ls));
memset(stack,0,sizeof(stack));
memset(ex,0,sizeof(ex));
memset(ey,0,sizeof(ey));
memset(X,0,sizeof(X));
memset(Y,0,sizeof(Y));
memset(C,0,sizeof(C));
memset(cir,0,sizeof(cir));
for(int i=0;i<=1000;i++)
{
sat[i].clear();
}
}
void TARJAN(int x)
{
dfn[x]=low[x]=++num;
stack[++jl]=x;
vis[x]=1;
for(int i=0;i<sat[x].size();i++)
{
int to=sat[x][i];
if(!dfn[to])
{
TARJAN(to);
low[x]=min(low[x],low[to]);
}
else
{
if(vis[to])
{
low[x]=min(low[x],dfn[to]);
}
}
}
if(low[x]==dfn[x])
{
qlt++;
while(stack[jl]!=x)
{
ls[stack[jl]]=qlt;
vis[stack[jl]]=0;
jl--;
}
ls[stack[jl]]=qlt;
vis[stack[jl]]=0;
jl--;
}
}
int LINYIN()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)
{
scanf("%d%d",&ex[i],&ey[i]);
if(ex[i]>ey[i])
swap(ex[i],ey[i]);
}
for(int i=1;i<=n;i++)
{
scanf("%d",&C[i]);
ID[C[i]]=i;
if(i>1)
{
a1=C[i-1];
a2=C[i];
if(a1<a2)
{
cir[a1][a2]=1;
}
else
cir[a2][a1]=1;
}
}
if(m>3*n-6)
{
printf("NO\n");
return 0;
}
a1=C[n],a2=C[1];
if(a1<a2)
{
cir[a1][a2]=1;
}
else
cir[a2][a1]=1;
for(int i=1;i<=m;i++)
{
if(cir[ex[i]][ey[i]])
continue;
X[++cnt]=ex[i];
Y[cnt]=ey[i];
}
for(int i=1;i<cnt;i++)
{
for(int j=i+1;j<=cnt;j++)
{
int u1=ID[X[i]],v1=ID[Y[i]],u2=ID[X[j]],v2=ID[Y[j]];
if(u1>v1)
swap(u1,v1);
if(u2>v2)
swap(u2,v2);
if((u1<u2&&v1>u2&&v1<v2)||(u1>u2&&u1<v2&&v1>v2))
{
sat[i].push_back(j+cnt);
sat[i+cnt].push_back(j);
sat[j].push_back(i+cnt);
sat[j+cnt].push_back(i);
}
}
}
for(int i=1;i<=cnt*2;i++)
{
if(!dfn[i])
TARJAN(i);
}
for(int i=1;i<=cnt;i++)
{
if(ls[i]==ls[i+cnt])
{
cout<<"NO"<<endl;
return 0;
}
}
cout<<"YES"<<endl;
return 0;
}
int main()
{
freopen("planar.in","r",stdin);
freopen("planar.out","w",stdout);
scanf("%d",&t);
while(t--)
{
init();
LINYIN();
}
return 0;
}