BZOJ1997: [Hnoi2010]Planar

来源:互联网 发布:软件研发项目立项 编辑:程序博客网 时间:2024/05/19 13:09

先将哈密顿回路展在平面上,尝试给他连上原图中的其他边
每条边我们可以画在环内或者环外,有些边之间有冲突,不能同时在环内或环外,这就对应了一个2-SAT模型
直接tarjan判一下有没有u,u’在同一个连通分量就行了
边数是m^2的,Tm^2会T
因为平面图有个性质 m<=3n-6,用这个剪枝就行了

code:

#include<set>#include<map>#include<deque>#include<queue>#include<stack>#include<cmath>#include<ctime>#include<bitset>#include<string>#include<vector>#include<cstdio>#include<cstdlib>#include<cstring>#include<climits>#include<complex>#include<iostream>#include<algorithm>#define ll long longusing namespace std;inline void down(int &x,const int &y){if(x>y)x=y;}const int maxn = 11000;const int maxm = 110000;int n,m;int e[maxm][2];int te[maxn],tp;struct edge{int y,nex;}a[maxm<<1]; int len,fir[maxm];inline void ins(const int x,const int y){a[++len]=(edge){y,fir[x]};fir[x]=len;}int t[maxn],id[maxn];int dfn[maxn],low[maxn],did;int cnt,bel[maxn];int sta[maxn],sn;bool insta[maxn];void tarjan(const int x){    dfn[x]=low[x]=++did; insta[sta[++sn]=x]=true;    for(int k=fir[x],y=a[k].y;k;k=a[k].nex,y=a[k].y)    {        if(!dfn[y]) tarjan(y),down(low[x],low[y]);        else if(insta[y]) down(low[x],dfn[y]);    }    if(low[x]==dfn[x])    {        int la=0; cnt++;        while(la!=x)        {            bel[la=sta[sn--]]=cnt;            insta[la]=false;        }    }}int main(){    int tcase; scanf("%d",&tcase);    while(tcase--)    {        scanf("%d%d",&n,&m);        for(int i=1;i<=m;i++) scanf("%d%d",&e[i][0],&e[i][1]);        for(int i=1;i<=n;i++) scanf("%d",&t[i]),id[t[i]]=i;        if(m>3*n-6) { puts("NO");continue; }        tp=0;        for(int i=1;i<=m;i++)        {            int x=id[e[i][0]],y=id[e[i][1]];            if(x>y) swap(x,y),swap(e[i][0],e[i][1]);            if(x+1==y||(x==1&&y==n)) continue;            te[++tp]=i;        }        len=0; for(int i=1;i<=2*tp;i++) fir[i]=dfn[i]=0;        for(int i=1;i<=tp;i++)        {            int x=id[e[te[i]][0]],y=id[e[te[i]][1]];            for(int j=i+1;j<=tp;j++)            {                int xx=id[e[te[j]][0]],yy=id[e[te[j]][1]];                bool flag=false;                if(x<xx)                {                    if(xx<y&&y<yy) flag=true;                }                else if(xx<x)                {                    if(x<yy&&yy<y) flag=true;                }                if(flag) ins(2*i-1,2*j),ins(2*i,2*j-1),ins(2*j-1,2*i),ins(2*j,2*i-1);            }        }        cnt=did=0;        for(int i=1;i<=2*tp;i++) if(!dfn[i]) tarjan(i);        bool re=true;        for(int i=1;i<=tp;i++)            if(bel[2*i-1]==bel[2*i]) { re=false; break; }        puts(re?"YES":"NO");    }    return 0;}
原创粉丝点击