# 洛谷P3209 [HNOI2010]PLANAR(2-SAT)

2018-03-01 12:22:04来源:cnblogs.com作者:自为风月马前卒人点击

## 输入输出样例

`26 91 41 51 62 42 52 63 43 53 61 4 2 5 3 65 51 22 33 44 55 11 2 3 4 5`

`NOYES`

## 说明

`#include<cstdio>#include<cstring>#include<algorithm>#include<stack>#include<vector>#include<queue>#include<iostream>#define Pair pair<int,int>#define F first#define S secondusing namespace std;const int MAXN=1e6+10;//#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<20,stdin),p1==p2)?EOF:*p1++)char buf[1<<20],*p1=buf,*p2=buf;inline int read(){    char c=getchar();int x=0,f=1;    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}    while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}    return x*f;}struct node{    int u,v,nxt;}edge[MAXN];int head[MAXN],num=1;inline void AddEdge(int x,int y){    edge[num].u=x;    edge[num].v=y;    edge[num].nxt=head[x];    head[x]=num++;}int happen[MAXN];int dfn[MAXN],low[MAXN],tot,color[MAXN],colornum=0,vis[MAXN];stack<int>s;int N,M;Pair P[MAXN];void tarjan(int now){    dfn[now]=low[now]=++tot;    s.push(now);    vis[now]=1;    for(int i=head[now];i!=-1;i=edge[i].nxt)    {        if(!dfn[edge[i].v])            tarjan(edge[i].v),low[now]=min(low[now],low[edge[i].v]);        else if(vis[edge[i].v]) low[now]=min(low[now],dfn[edge[i].v]);    }    if(dfn[now]==low[now])    {        int h;colornum++;        do        {            h=s.top();s.pop();            vis[h]=0;            color[h]=colornum;        }while(h!=now);    }}void pre(){    memset(dfn,0,sizeof(dfn));    memset(low,0,sizeof(low));    memset(head,-1,sizeof(head));    memset(color,0,sizeof(color));    memset(happen,0,sizeof(happen));    memset(vis,0,sizeof(vis));    num=1;}int main(){    #ifdef WIN32    freopen("a.in","r",stdin);    freopen("a.out","w",stdout);    #else    #endif    int QWQ=read();    while(QWQ--)    {        pre();        N=read();M=read();        for(int i=1;i<=M;i++)            P[i].F=read(),P[i].S=read();        for(int i=1;i<=N;i++)        {            int p=read();            happen[p]=i;        }        if(M>3*N-6){printf("NO/n"); continue;}        for(int i=1;i<=M;i++)        {            P[i].F=happen[P[i].F];            P[i].S=happen[P[i].S];            if(P[i].F>P[i].S) swap(P[i].F,P[i].S);        }        for(int i=1;i<=M;i++)            for(int j=i+1;j<=M;j++)                if((P[i].S>P[j].F&&P[i].F<P[j].F&&P[i].S<P[j].S)                 ||(P[i].F>P[j].F&&P[i].S>P[j].S&&P[i].F<P[j].S))                     AddEdge(i,j+M),                     AddEdge(j+M,i),                     AddEdge(j,i+M),                     AddEdge(i+M,j);        for(int i=1;i<=2*M;i++)            if(!dfn[i])                tarjan(i);        int flag=1;        for(int i=1;i<=2*M;i++)            if(color[i]==color[i+M])                {printf("NO/n");flag=0;break;}        if(flag==1) printf("YES/n");        }    return 0;}`