# [BZOJ1997] [Hnoi2010]Planar - 2-SAT

## 1997: [Hnoi2010]Planar

Time Limit: 10 Sec  Memory Limit: 64 MB
Submit: 2639  Solved: 1015
[Submit][Status][Discuss]

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

NO
YES

## HINT

2—SAT裸题...

Code

#include <iostream>
#include <cstdio>
#include <vector>
#include <cstring>
using namespace std;
int T, n, m;
int L[10010], R[10010], num;
struct edge{
int nxt,to;
}ed[1000005];
int dfn[5005], low[5005], dfnn;
int stack[5005], top, C[5005], scc;
bool ins[5005];
int pos[5005], D[5005];
void Tarjan(int x)
{
dfn[x] = low[x] = ++dfnn;
stack[++top] = x, ins[x] = 1;
for (register int i = head[x] ; i ; i = ed[i].nxt)
{
int to = ed[i].to;
if (!dfn[to]){Tarjan(to);low[x]=min(low[x],low[to]);}
else if(ins[to]) low[x] = min(low[x], low[to]);
}
if (dfn[x] == low[x])
{
scc++;int y;
do{
y = stack[top--], ins[y] = 0;
C[y] = scc;
}while(y != x);
}
}
inline void init()
{
cnt=1;top=0;dfnn=0;num=0;scc=0;
memset(ins, 0, sizeof ins);
memset(C, 0, sizeof C);
memset(stack, 0, sizeof stack);
memset(pos, 0, sizeof pos);
memset(dfn, 0, sizeof dfn);
memset(low, 0, sizeof low);
memset(D, 0, sizeof D);
//    cleann(ins, 0), cleann(C, 0), cleann(head, 0), cleann(stack, 0);
//    cleann(pos, 0), cleann(dfn, 0), cleann(low, 0),cleann(D, 0);
}
int main()
{
scanf("%d", &T);
while (T--)
{
init();
scanf("%d%d", &n, &m);
for (register int i = 1 ; i <= m ; i ++)
scanf("%d%d", &L[i], &R[i]);
for (register int i = 1 ; i <= n ; i ++)
scanf("%d", &D[i]);
if (m > 3 * n - 6) {puts("NO");continue;}
for (register int i = 1 ; i <= n ; i ++)
pos[D[i]] = i;
for (register int i = 1 ; i <= m ; i ++)
{
R[i] = pos[R[i]], L[i] = pos[L[i]];
if (R[i] < L[i]) swap(R[i], L[i]);//R[i] > L[i]
if (R[i] - L[i] == 1 or (R[i] == n and L[i] == 1)) continue;
L[++num] = L[i], R[num] = R[i];
}
for (register int i = 1 ; i <= num ; i ++)
{
for (register int j = 1 ; j <= num ; j ++)
{
if (i == j) continue;
if ((L[i] > L[j] and R[j] > L[i] and R[j] < R[i]) or (L[i] < L[j] and R[j] > R[i] and R[i] > L[j]))
{
}
}
}
for (register int i = 1 ; i <= 2 * num ; i ++) if (!dfn[i]) Tarjan(i);
bool flag = 0;
for (register int i = 1 ; i <= num ; i ++)
{
if (C[i] == C[i + num]) {puts("NO");flag = 1;break;}
}

if (!flag)puts("YES");
}
}

posted @ 2018-07-07 23:05  zZhBr  阅读(105)  评论(0编辑  收藏  举报