比赛 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;
}