zoukankan      html  css  js  c++  java
  • 题解 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;
    }
    
  • 相关阅读:
    JVM heap中各generation的大小(Sizing the Generations)
    MySQL中分组取第一条, 以及删除多余的重复记录
    八芯网线水晶头做法(线序)
    Win7命令行下查看无线网络信息
    OpenWrt的开机启动服务(init scripts)
    犀牛书的实例代码:给对象添加freeze, hide, 查询descriptors
    ES6新特性:Javascript中Generator(生成器)
    ES6新特性:Function函数扩展, 扩展到看不懂
    ES6新特性:Javascript中的Map和WeakMap对象
    ES6新特性:Javascript中Set和WeakSet类型的数据结构
  • 原文地址:https://www.cnblogs.com/colazcy/p/12236318.html
Copyright © 2011-2022 走看看