[BZOJ1997][HNOI2010]Planar(2-SAT)
2017-12-02 11:52
423 查看
首先,平面图的性质:边数小于等于3n−6。不符合的直接跳过。
然后可以发现,对于哈密尔顿环之外的任意一条边,要么连在环内部,要么连在环外部。在一定的条件下(可以简单判断),如果两条边同时连在环内部或同时连在环外部,这两条边就一定会相交,这样的限制条件符合2-SAT的模型。
把第i条边拆成i和i′,i表示这条边连在内部,i′表示连在外部。
对于任意两条不在哈密尔顿环上的边i,j,i≠j,如果他们不能同时连在环内或环外,则:
1、建边<i,j′>,表示i在内则j必须在外。
2、建边<i′,j>,表示i在外则j必须在内。
3、建边<j,i′>,表示j在内则i必须在外。
4、建边<j′,i>,表示j在外则i必须在内。
然后求一遍强连通分量,如果存在一个i和i′在同一个强连通分量里,那么原图不是平面图,否则是平面图。
代码:
然后可以发现,对于哈密尔顿环之外的任意一条边,要么连在环内部,要么连在环外部。在一定的条件下(可以简单判断),如果两条边同时连在环内部或同时连在环外部,这两条边就一定会相交,这样的限制条件符合2-SAT的模型。
把第i条边拆成i和i′,i表示这条边连在内部,i′表示连在外部。
对于任意两条不在哈密尔顿环上的边i,j,i≠j,如果他们不能同时连在环内或环外,则:
1、建边<i,j′>,表示i在内则j必须在外。
2、建边<i′,j>,表示i在外则j必须在内。
3、建边<j,i′>,表示j在内则i必须在外。
4、建边<j′,i>,表示j在外则i必须在内。
然后求一遍强连通分量,如果存在一个i和i′在同一个强连通分量里,那么原图不是平面图,否则是平面图。
代码:
#include <cmath> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; inline int read() { int res = 0; bool bo = 0; char c; while (((c = getchar()) < '0' || c > '9') && c != '-'); if (c == '-') bo = 1; else res = c - 48; while ((c = getchar()) >= '0' && c <= '9') res = (res << 3) + (res << 1) + (c - 48); return bo ? ~res + 1 : res; } const int V = 205, N = 3e4 + 5, M = 2e6 + 5; int n, m, eX , eY , Cir[V], ecnt, nxt[M], adj , go[M], dfn , low , top, times, stk , bel , sum, rev[V], Ex , Ey ; bool cir[V][V], ins ; void add_edge(int u, int v) { nxt[++ecnt] = adj[u]; adj[u] = ecnt; go[ecnt] = v; } void Tarjan(int u) { dfn[u] = low[u] = ++times; stk[++top] = u; ins[u] = 1; for (int e = adj[u], v; e; e = nxt[e]) if (!dfn[v = go[e]]) { Tarjan(v); low[u] = min(low[u], low[v]); } else if (ins[v]) low[u] = min(low[u], dfn[v]); if (dfn[u] == low[u]) { int v; bel[u] = ++sum; ins[u] = 0; while (v = stk[top--], v != u) bel[v] = sum, ins[v] = 0; } } bool check() { int i; for (i = 1; i <= (m << 1); i++) if (!dfn[i]) Tarjan(i); for (i = 1; i <= m; i++) if (bel[i] == bel[i + m]) return 0; return 1; } void work() { ecnt = times = sum = 0; memset(adj, 0, sizeof(adj)); memset(dfn, 0, sizeof(dfn)); memset(bel, 0, sizeof(bel)); memset(low, 0, sizeof(low)); memset(cir, 0, sizeof(cir)); int i, j, u, v, x, y, tot = 0; n = read(); m = read(); for (i = 1; i <= m; i++) { eX[i] = read(); eY[i] = read(); if (eX[i] > eY[i]) swap(eX[i], eY[i]); } for (i = 1; i <= n; i++) { rev[Cir[i] = read()] = i; if (i > 1) { x = Cir[i - 1]; y = Cir[i]; if (x < y) cir[x][y] = 1; else cir[y][x] = 1; } } if (m > 3 * n - 6) return (void) (printf("NO\n")); x = Cir ; y = Cir[1]; ((x < y) ? cir[x][y] : cir[y][x]) = 1; for (i = 1; i <= m; i++) { if (cir[eX[i]][eY[i]]) continue; Ex[++tot] = eX[i]; Ey[tot] = eY[i]; } m = tot; for (i = 1; i < m; i++) for (j = i + 1; j <= m; j++) { u = rev[Ex[i]], v = rev[Ey[i]], x = rev[Ex[j]], y = rev[Ey[j]]; if (u > v) swap(u, v); if (x > y) swap(x, y); if ((u < x && v > x && v < y) || (u > x && u < y && v > y)) { add_edge(i, j + m); add_edge(i + m, j); add_edge(j, i + m); add_edge(j + m, i); } } printf(check() ? "YES\n" : "NO\n"); } int main() { int T = read(); while (T--) work(); return 0; }
相关文章推荐
- BZOJ 1997 HNOI 2010 Planar 2-SAT
- 【2-SAT(tarjan)】BZOJ1997-[Hnoi2010]Planar
- 【BZOJ1997】[Hnoi2010]Planar 2-SAT
- BZOJ 1997: [Hnoi2010]Planar [2-SAT]
- [BZOJ1997][Hnoi2010]Planar 2-sat (联通分量) 平面图
- BZOJ 1997: [Hnoi2010]Planar|2-SAT|二分图染色
- [BZOJ 1997][HNOI2010]Planar(2-SAT)
- [BZOJ1997][Hnoi2010]Planar(2-SAT)
- [bzoj1997][Hnoi2010]Planar(2-sat||括号序列)
- BZOJ 1997 HNOI 2010 Planar 2-SAT
- bzoj 1997: [Hnoi2010]Planar (2-SAT)
- 【BZOJ1997】[Hnoi2010]Planar【平面图判定】【2-SAT】
- [bzoj1997][Hnoi2010]Planar 2-sat
- bzoj1997[Hnoi2010]Planar 2-SAT
- [BZOJ1997][Hnoi2010]Planar(2-SAT)
- BZOJ.1997.[HNOI2010]Planar(2-SAT)
- 【平面图判定+2-SAT验证】BZOJ1997 [Hnoi2010]Planar
- [BZOJ1997][HNOI2010][2-sat]Planar
- BZOJ 1997 Hnoi2010 Planar 2-sat
- BZOJ 1997 [Hnoi2010]Planar - 2-sat