bzoj1997 [Hnoi2010]Planar 2-SAT

Description


若能将无向图G=(V,E)画在平面上使得任意两条无重合顶点的边不相交,则称G是平面图。判定一个图是否为平面图的问题是图论中的一个重要问题。现在假设你要判定的是一类特殊的图,图中存在一个包含所有顶点的环,即存在哈密顿回路。

Solution


考虑把哈密顿路径画成一个圈,那么剩下的路径要么在圆外要么在圆内。问题变成求是否存在一种方案使得所有边不相交
这是一个很经典的2-SAT模型,对于两条相交的边分别连(i,j’)和(i’,j)然后tarjan即可

同时我们还需要知道一个结论,那就是若一个图m>3n-6则这个图一定不是平面图
这样暴力连边的复杂度就是十分科学的了

Code


#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <stack>
#define rep(i,st,ed) for (int i=st;i<=ed;++i)
#define fill(x,t) memset(x,t,sizeof(x))
#define fi first
#define se second

typedef std:: pair <int,int> pair;
const int N=1205;
const int E=N*N;

struct edge {int y,next;} e[E];

std:: stack<int> stack;
pair g[E];

int dfn[N],low[N],bel[N],id[N];
int ls[N],edCnt;

bool vis[N];

int read() {
    int x=0,v=1; char ch=getchar();
    for (;ch<'0'||ch>'9';v=(ch=='-')?(-1):(v),ch=getchar());
    for (;ch<='9'&&ch>='0';x=x*10+ch-'0',ch=getchar());
    return x*v;
}

void add_edge(int x,int y) {
    e[++edCnt]=(edge) {y,ls[x]}; ls[x]=edCnt;
    e[++edCnt]=(edge) {x,ls[y]}; ls[y]=edCnt;
}

void dfs(int now) {
    dfn[now]=low[now]=++dfn[0];
    stack.push(now); vis[now]=1;
    for (int i=ls[now];i;i=e[i].next) {
        if (!dfn[e[i].y]) {
            dfs(e[i].y);
            low[now]=std:: min(low[now],low[e[i].y]);
        } else if (vis[e[i].y]) {
            low[now]=std:: min(low[now],dfn[e[i].y]);
        }
    }
    if (dfn[now]==low[now]) {
        int y=0; bel[0]++;
        while (y!=now) {
            y=stack.top(); stack.pop();
            bel[y]=bel[0]; vis[y]=0;
        }
    }
}

void tarjan(int n) {
    fill(dfn,0); fill(low,0); bel[0]=0;
    rep(i,1,n) if (!dfn[i]) dfs(i);
}

int main(void) {
    for (int T=read();T--;) {
        int n=read(),m=read();
        rep(i,1,m) g[i]=pair(read(),read());
        rep(i,1,n) id[read()]=i;
        rep(i,1,m) g[i]=pair(id[g[i].fi],id[g[i].se]);
        rep(i,1,m) g[i]=pair(std:: min(g[i].fi,g[i].se),std:: max(g[i].fi,g[i].se));
        if (m>n*3-6) {
            puts("NO"); continue;
        }
        fill(ls,0); edCnt=0;
        rep(i,1,m) rep(j,i+1,m) {
            if (g[i].fi<g[j].fi&&g[i].se>g[j].fi&&g[i].se<g[j].se) {
                add_edge(i,j+m);
                add_edge(j,i+m);
            } else if (g[i].fi>g[j].fi&&g[i].fi<g[j].se&&g[i].se>g[j].se) {
                add_edge(i,j+m);
                add_edge(j,i+m);
            }
        }
        tarjan(m*2);
        bool flag=true;
        rep(i,1,m) if (bel[i]==bel[i+m]) {
            flag=false; break;
        }
        if (flag) puts("YES");
        else puts("NO");
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/jpwang8/article/details/80877970
今日推荐