[HNOI 2010]Planar
阿新 • • 發佈:2018-03-12
dig struct fin esp online plan body 復雜 染色法
Description
題庫鏈接
給出 \(T\) 個 \(N\) 個節點 \(M\) 條邊的無向圖(無重邊自環),並給出它們各自的哈密頓回路。分別判斷每個圖是否是平面圖。
\(T\leq 100,3\leq N\leq 200,M\leq 10000\)
Solution
考慮一個帶哈密頓回路的無向圖,如果它是一個平面圖,即可以畫在平面上使得沒有 \(2\) 條邊需要交叉,那麽哈密頓圈之外的邊要麽畫在圈內,要麽畫在圈外。
(綠色的環是哈密頓圈)
如果兩條邊 \(e,f\) ,把它們都畫在圈的內側會相交,那麽都畫在外側也一定會相交。
也就是說,對於兩條邊,要麽沒有相互約束,要麽有一條約束:它們不能在圈的同側。
求出所有邊和邊的約束關系,用黑白染色法判斷約束關系是否為二分圖。
如果是二分圖,則原圖是平面圖。否則原圖不是平面圖。
似乎 \(O(M^2)\) 暴力建邊不可取,但註意到的是簡單極大平面圖的邊數 \(M\) 和節點數 \(N\) 滿足關系: \[M=3N-6\]
證明:
註意到平面圖歐拉定理 \(n-m+r=2\) , \(n\) 個節點, \(m\) 條邊, \(r\) 個面。
顯然對於極大平面圖 \(3r=2m\) ,帶入得 \(m=3n-6\) 。
顯然當 \(m>3n-6\) 時,這個圖一定不是平面圖,特判掉就好了。顯然這時 \(n\) 與 \(m\) 同階。復雜度得到了保障。
Code
//It is made by Awson on 2018.3.12
#include <bits/stdc++.h>
#define LL long long
#define dob complex<double>
#define Abs(a) ((a) < 0 ? (-(a)) : (a))
#define Max(a, b) ((a) > (b) ? (a) : (b))
#define Min(a, b) ((a) < (b) ? (a) : (b))
#define Swap(a, b) ((a) ^= (b), (b) ^= (a), (a) ^= (b))
#define writeln(x) (write(x), putchar('\n'))
#define lowbit(x) ((x)&(-(x)))
using namespace std;
const int N = 200, M = 10000;
void read(int &x) {
char ch; bool flag = 0;
for (ch = getchar(); !isdigit(ch) && ((flag |= (ch == '-')) || 1); ch = getchar());
for (x = 0; isdigit(ch); x = (x<<1)+(x<<3)+ch-48, ch = getchar());
x *= 1-2*flag;
}
void print(int x) {if (x > 9) print(x/10); putchar(x%10+48); }
void write(int x) {if (x < 0) putchar('-'); print(Abs(x)); }
int n, m, u[M+5], v[M+5], id[N+5], x;
struct tt {int to, next; }edge[(M<<5)+5];
int path[M+5], top, color[M+5];
bool dfs(int o, int col) {
color[o] = col;
for (int i = path[o]; i; i = edge[i].next) {
if (color[edge[i].to] == col) return false;
if (color[edge[i].to] == -1) if (!dfs(edge[i].to, col^1)) return false;
}
return true;
}
void add(int u, int v) {edge[++top].to = v, edge[top].next = path[u], path[u] = top; }
void work() {
read(n), read(m); top = 0; memset(path, 0, sizeof(path));
for (int i = 1; i <= m; i++) read(u[i]), read(v[i]);
for (int i = 1; i <= n; i++) read(x), id[x] = i;
if (m > 3*n-6) {puts("NO"); return; }
for (int i = 1; i <= m; i++) {
if (id[u[i]] > id[v[i]]) Swap(u[i], v[i]);
for (int j = 1; j < i; j++)
if ((id[u[i]] < id[u[j]] && id[v[i]] < id[v[j]] && id[u[j]] < id[v[i]]) || (id[u[j]] < id[u[i]] && id[v[j]] < id[v[i]] && id[u[i]] < id[v[j]]))
add(i, j), add(j, i);
}
for (int i = 1; i <= m; i++) color[i] = -1;
for (int i = 1; i <= m; i++)
if (color[i] == -1) if (dfs(i, 0) == 0) {puts("NO"); return; }
puts("YES");
}
int main() {
int t; read(t); while (t--) work(); return 0;
}
[HNOI 2010]Planar