【BZOJ1997】【HNOI2010】Planar
1606 ワード
【タイトルリンク】クリックしてリンク を開く
【考え方のポイント】のアーカイブブログで、問題はありません.
【コード】
【考え方のポイント】
【コード】
#include
using namespace std;
#define MAXN 20005
int f[MAXN], x[MAXN], y[MAXN], home[MAXN], value[MAXN];
bool circle[MAXN];
int F(int x) {
if (f[x] == x) return x;
else return f[x] = F(f[x]);
}
int main() {
int T;
scanf("%d", &T);
while (T--) {
int n, m;
scanf("%d%d", &n, &m);
for (int i = 1; i <= m; i++)
scanf("%d%d", &x[i], &y[i]);
for (int i = 1; i <= n; i++) {
scanf("%d", &value[i]);
home[value[i]] = i;
}
for (int i = 1; i <= m; i++) {
x[i] = home[x[i]];
y[i] = home[y[i]];
if (x[i] > y[i]) swap(x[i], y[i]);
if (x[i] + 1 == y[i] || (x[i] == 1 && y[i] == n)) circle[i] = true;
else circle[i] = false;
}
if (m > 3 * n) {
printf("NO
");
continue;
}
for (int i = 1; i <= 2 * m + 1; i++)
f[i] = i;
for (int i = 1; i <= m; i++){
if (circle[i]) continue;
for (int j = i + 1; j <= m; j++) {
if (circle[j]) continue;
if (x[i] == x[j] || x[i] == y[j] || y[i] == x[j] || y[i] == y[j]) continue;
if ((x[j] > x[i] && x[j] < y[i]) ^ (y[j] > x[i] && y[j] < y[i])) {
int tmp = i * 2, tnp = j * 2;
f[F(tmp)] = F(tnp ^ 1);
f[F(tnp)] = F(tmp ^ 1);
}
}
}
bool flg = true;
for (int i = 1; i <= m; i++)
if (F(i * 2) == F(i * 2 ^ 1)) {
flg = false;
break;
}
if (flg) printf("YES
");
else printf("NO
");
}
return 0;
}