题解 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;
}

猜你喜欢

转载自www.cnblogs.com/colazcy/p/12236318.html