P3209 平面图判定 做题记录
这种题我是非常讨厌的,你必须要知道平面图的性质才能做这道题,性质是:NO 就行了。
然后我们来看 2-SAT 的做法:这道题搞清楚这个就跟这个一样,由于环上数字的顺序不是从小到大顺时针排的,但是我们仍然可以记录每个数字在环上的顺序 ord 然后来判断是否相交,另外这道题拆的元素是
代码:
//Just Sayori
#include <iostream>
#include <cstdio>
#include <algorithm>
#define ll long long
#define rnt register int
#define gr getchar
#define pr putchar
#define N 40005
#define M 500005
using namespace std;
inline ll read()
{
ll x = 0, f = 1;
char ch = gr();
while (ch < '0' || ch > '9')
ch == '-' ? f = -1, ch = gr() : ch = gr();
while (ch >= '0' && ch <= '9')
x = (x << 3) + (x << 1) + (ch ^ 48), ch = gr();
return x * f;
}
inline void write(ll x)
{
static int top = 0, sta[39];
if (x < 0)
pr('-');
do
sta[++top] = x % 10, x /= 10;
while (x);
while (top)
pr(sta[top--] ^ 48);
}
struct edge
{
int v, next;
} e[M << 1];
int head[N], cnt;
inline void add(int u, int v)
{
e[++cnt] = {v, head[u]}, head[u] = cnt;
}
int n, m, a, bcc, top;
int x[N], y[N], dfn[N], low[N], num[N], vis[N], ord[N], stack[N];
void tarjan(int u)
{
dfn[u] = low[u] = ++cnt;
vis[u] = 1, stack[++top] = u;
for (rnt i = head[u]; i; i = e[i].next)
{
int v = e[i].v;
if (!dfn[v])
tarjan(v), low[u] = min(low[u], low[v]);
else if (vis[v])
low[u] = min(low[u], dfn[v]);
}
if (dfn[u] == low[u])
{
bcc++;
while (stack[top + 1] != u)
num[stack[top]] = bcc, vis[stack[top--]] = 0;
}
}
int main()
{
int time = read();
while (time--)
{
bool f = 1;
n = read(), m = read();
for (rnt i = 1; i <= m; i++)
x[i] = read(), y[i] = read();
for (rnt i = 1; i <= n; i++)
a = read(), ord[a] = i;
if (m > 3 * n - 6)
{
puts("NO");
continue;
}
for (rnt i = 1; i <= m; i++)
if (ord[x[i]] > ord[y[i]])
swap(x[i], y[i]);
for (rnt i = 2; i <= m; i++)
for (rnt j = 1; j < i; j++)
if ((ord[x[i]] < ord[x[j]] && ord[x[j]] < ord[y[i]] && ord[y[i]] < ord[y[j]]) || (ord[x[j]] < ord[x[i]] && ord[x[i]] < ord[y[j]] && ord[y[j]] < ord[y[i]]))
add(i, j + m), add(i + m, j), add(j, i + m), add(j + m, i);
for (rnt i = 1; i <= 2 * m; i++)
if (!dfn[i])
tarjan(i);
for (rnt i = 1; i <= m; i++)
if (num[i] == num[i + m])
f = 0;
if (f)
puts("YES");
else
puts("NO");
for (rnt i = 1; i <= 2 * m; i++)
dfn[i] = num[i] = vis[i] = head[i] = stack[i] = 0;
bcc = cnt = top = 0;
}
return 0;
}