题解 P3209 【[HNOI2010]平面图判定】

边不一定在环内!

题目链接

Solution [HNOI2010]平面图判定

题目大意:给定一个存在哈密顿回路的图,判定它是不是平面图

2-SAT


分析:

首先有一个性质:对于极大平面图,有(m = 3n - 6)

萌新yy的证明:考虑归纳法

对于(n=3)时,(m=3),成立

因为是极大平面图,所以我们每新加入一个点希望增加的边尽量多,我们贪心的加入三角形中,每加入一个点增加(3)条边,证毕

所以对于(m > 3n-6)一定不存在平面图,所以(m leq 594)

然后对于一条边,我们可以把它放在环内也可以把它放在环外,我们(m^2)暴力枚举每一对边,如果两边同时放在环内相交,它们就不能同时存在于环内(或环外),2-SAT即可

对点重新标号貌似会比较简单的样子……

#include <algorithm>
#include <cstdio>
#include <cctype>
#include <vector>
#include <stack>
using namespace std;
inline int read(){
	int x = 0;char c = getchar();
	while(!isdigit(c))c = getchar();
	while(isdigit(c))x = x * 10 + c - '0',c = getchar();
	return x;
}
namespace graph{
	const int maxn = 3e4;
	vector<int> G[maxn];
	inline void addedge(int from,int to){G[from].push_back(to);}
	int dfn[maxn],low[maxn],col[maxn],instk[maxn],col_tot,dfs_tot;
	stack<int> stk;
	inline void tarjan(int u){
		dfn[u] = low[u] = ++dfs_tot;
		stk.push(u),instk[u] = 1;
		for(int v : G[u])
			if(!dfn[v])tarjan(v),low[u] = min(low[u],low[v]);
			else if(instk[v])low[u] = min(low[u],dfn[v]);
		if(low[u] == dfn[u]){
			int t;
			col_tot++;
			do{
				t = stk.top();stk.pop(),instk[t] = 0;
				col[t] = col_tot;
			}while(t != u);
		}
	}
}
struct Edge{int from,to;}Edges[16384];
int n,m,t,to[256];
inline int qaq(int a,int b,int x){return a < x && x < b;}
inline int qwq(int a,int b,int x){return x < a || x > b;}
inline void solve(){
	graph::col_tot = graph::dfs_tot = 0;
	for(int i = 1;i <= 2 * m;i++)graph::dfn[i] = graph::low[i] = graph::col[i] = graph::instk[i] = 0,graph::G[i].clear();
	n = read(),m = read();
	for(int i = 1;i <= m;i++)Edges[i].from = read(),Edges[i].to = read();
	for(int i = 1;i <= n;i++)to[read()] = i;
	if(m > 3 * n - 6){
		puts("NO");
		return;
	}
	for(int i = 1;i <= m;i++){
		Edge &e = Edges[i];
		e.from = to[e.from];
		e.to = to[e.to];
		if(e.from > e.to)swap(e.from,e.to);
	}
	for(int i = 1;i <= m;i++)
		for(int j = 1;j < i;j++){
			const Edge &a = Edges[i],&b = Edges[j];
			if((qaq(a.from,a.to,b.from) && qwq(a.from,a.to,b.to)) || (qaq(a.from,a.to,b.to) && qwq(a.from,a.to,b.from))){
				graph::addedge(i,j + m);
				graph::addedge(j + m,i);
				graph::addedge(i + m,j);
				graph::addedge(j,i + m);
			}
		}
	for(int i = 1;i <= 2 * m;i++)
		if(!graph::dfn[i])graph::tarjan(i);
	for(int i = 1;i <= m;i++)
		if(graph::col[i] == graph::col[i + m]){
			puts("NO");
			return;
		}
	puts("YES");
}
int main(){
	t = read();
	while(t--)solve();
	return 0;
}
原文地址:https://www.cnblogs.com/colazcy/p/12236318.html