• 【系列】 2-SAT


    bzoj 1997 Planar

    题目大意:

    给一个存在曼哈顿回路的无向图,求该图是否为平面图

    思路:

    先把曼哈顿回路提出来,则剩下的边的两个端点若有$ABAB$的形式则这两条边必定一个在环外一个在环内

    对于这些边$2-SAT$即可

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<cstdlib>
     5 #include<cmath>
     6 #include<algorithm>
     7 #include<queue>
     8 #include<vector>
     9 #include<map>
    10 #include<set>
    11 #define ll long long
    12 #define db double
    13 #define inf 2139062143
    14 #define MAXN 20100
    15 #define rep(i,s,t) for(register int i=(s),i##__end=(t);i<=i##__end;++i)
    16 #define dwn(i,s,t) for(register int i=(s),i##__end=(t);i>=i##__end;--i)
    17 #define ren for(register int i=fst[x];i;i=nxt[i])
    18 #define Fill(x,t) memset(x,t,sizeof(x))
    19 #define pb(i,x) vec[i].push_back(x)
    20 #define pls(a,b) (a+b)%MOD
    21 #define mns(a,b) (a-b+MOD)%MOD
    22 #define mul(a,b) (1LL*(a)*(b))%MOD
    23 using namespace std;
    24 inline int read()
    25 {
    26     int x=0,f=1;char ch=getchar();
    27     while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
    28     while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
    29     return x*f;
    30 }
    31 int n,m,nxt[MAXN*100],fst[MAXN],to[MAXN*100],cnt,u[MAXN],v[MAXN],cir[MAXN];
    32 int dfn[MAXN],low[MAXN],bl[MAXN],stp,st[MAXN],top,scc,hsh[MAXN];
    33 void add(int u,int v) {nxt[++cnt]=fst[u],fst[u]=cnt,to[cnt]=v;}
    34 void mem()
    35 {
    36     Fill(fst,0);Fill(dfn,0);Fill(cir,0);Fill(bl,0);
    37     cnt=stp=top=scc=0;
    38 }
    39 int p(int x) {return u[x]%n+1==v[x]||(v[x]==n&&u[x]==1);}
    40 void tarjan(int x)
    41 {
    42     st[++top]=x,dfn[x]=low[x]=++stp;
    43     ren if(!dfn[to[i]]) {tarjan(to[i]);low[x]=min(low[x],low[to[i]]);}
    44         else if(!bl[to[i]]) low[x]=min(low[x],dfn[to[i]]);
    45     if(low[x]==dfn[x])
    46         {scc++;int now=0;while(now!=x) now=st[top--],bl[now]=scc;}
    47 }
    48 int cheq(){rep(i,1,m) if(bl[i]==bl[i+m]&&cir[i]) return 0;return 1;}
    49 int main()
    50 {
    51     int T=read();while(T--)
    52     {
    53         n=read(),m=read();mem();rep(i,1,m) u[i]=read(),v[i]=read();
    54         rep(i,1,n) hsh[read()]=i;if(m>3*n-6){puts("NO");continue;}
    55         rep(i,1,m) {u[i]=hsh[u[i]],v[i]=hsh[v[i]];if(u[i]>v[i]) swap(u[i],v[i]);}
    56         rep(i,1,m) cir[i]=1^p(i);rep(i,1,m) rep(j,1,m)
    57             if(cir[i]&&cir[j]&&i^j&&u[i]<u[j]&&u[j]<v[i]&&v[i]<v[j])
    58                 add(i+m,j),add(i,j+m),add(j,i+m),add(j+m,i);
    59         rep(i,1,m<<1) if(!dfn[i]&&cir[i]) tarjan(i);puts(cheq()?"YES":"NO");
    60     }
    61 }
    View Code

    bzoj 4945 游戏

    题目大意:

    有$n$个场地分为4种$x,a,b,c$,有三辆车$A$不能跑$a$,$B$不能跑$b$,$C$不能跑$c$,$x$所有都能跑

    给出一些限制形如$i,x,j,y$表示若$i$场地选了$x$这种车,则$j$场地必须选$y$这种车

    给出合法的安排车的方案或判断无解

    思路:

    每个不是$x$的场地可以选两种车,可以转化为$2-SAT$模型

    因为$x$的场地很少,枚举每个场地作为$A$或$B$复杂度$2^D$,不需要枚举选哪个车

    对每个限制,若$i$和$x$不合法,无视这个条件即可

    若$j$和$y$不合法,相当于强行选$ eg x$

    其余情况直接连这个限制与其逆否即可

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<cstdlib>
     5 #include<cmath>
     6 #include<algorithm>
     7 #include<queue>
     8 #include<vector>
     9 #include<map>
    10 #include<set>
    11 #define ll long long
    12 #define db double
    13 #define inf 2139062143
    14 #define MAXN 200100
    15 #define rep(i,s,t) for(register int i=(s),i##__end=(t);i<=i##__end;++i)
    16 #define dwn(i,s,t) for(register int i=(s),i##__end=(t);i>=i##__end;--i)
    17 #define ren for(register int i=fst[x];i;i=nxt[i])
    18 #define Fill(x,t) memset(x,t,sizeof(x))
    19 #define pls(a,b) (a+b)%MOD
    20 #define mns(a,b) (a-b+MOD)%MOD
    21 #define mul(a,b) (1LL*(a)*(b))%MOD
    22 using namespace std;
    23 inline int read()
    24 {
    25     int x=0,f=1;char ch=getchar();
    26     while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
    27     while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
    28     return x*f;
    29 }
    30 int n,D,m,g[MAXN],st[MAXN],dfn[MAXN],low[MAXN],stp,scc,bl[MAXN],top;
    31 int ux[MAXN],uy[MAXN],ox[MAXN],oy[MAXN],sp[10];
    32 int nxt[MAXN<<1],to[MAXN<<1],fst[MAXN],cnt;
    33 void add(int u,int v) {nxt[++cnt]=fst[u],fst[u]=cnt,to[cnt]=v;}
    34 struct Data{int a,id,b;};char s[MAXN],ta[2],tb[2];
    35 void tarjan(int x)
    36 {
    37     st[++top]=x,dfn[x]=low[x]=++stp;
    38     ren if(!dfn[to[i]]) {tarjan(to[i]);low[x]=min(low[x],low[to[i]]);}
    39         else if(!bl[to[i]]) low[x]=min(low[x],dfn[to[i]]);
    40     if(low[x]==dfn[x])
    41         {scc++;int now=-1;while(now!=x) now=st[top--],bl[now]=scc;}
    42 }
    43 int calc(int id,int x) {return g[id]==3?(id<<1)+(x==2):(id<<1)+(x==3);}
    44 int che()
    45 {
    46     Fill(dfn,0);Fill(bl,0);Fill(fst,0);top=scc=stp=cnt=0;int x,y;rep(i,1,m)
    47     {
    48         x=ux[i],y=uy[i];if(g[x]==ox[i]) continue;x=calc(x,ox[i]);
    49         if(g[y]==oy[i]) {add(x,x^1);continue;}
    50         y=calc(y,oy[i]);add(x,y);add(y^1,x^1);
    51     }
    52     rep(i,0,(n-1<<1)|1) if(!dfn[i]) tarjan(i);
    53     rep(i,0,n-1) if(bl[i<<1]==bl[i<<1|1]) return 0;
    54     rep(i,0,n-1) if(g[i]==1) printf("%c",(bl[i<<1]<bl[i<<1|1])?'B':'C');
    55     else if(g[i]==2) printf("%c",(bl[i<<1]<bl[i<<1|1])?'A':'C');
    56     else printf("%c",(bl[i<<1]<bl[i<<1|1])?'A':'B');return 1;
    57 }
    58 int main()
    59 {
    60     n=read(),D=read();int mxst=0;scanf("%s",s);rep(i,0,n-1)
    61         {g[i]=s[i]-'a'+1;if(g[i]>3) g[i]=0,sp[mxst++]=i;}
    62     m=read();rep(i,1,m) 
    63     {
    64         ux[i]=read()-1;scanf("%s",ta);uy[i]=read()-1;scanf("%s",tb);
    65         ox[i]=ta[0]-'A'+1,oy[i]=tb[0]-'A'+1;
    66     }
    67     mxst=1<<D;if(!D) {if(!che()) printf("-1");return 0;}rep(t,0,mxst-1)
    68         {rep(i,0,D-1) g[sp[i]]=((t>>i)&1)?2:1;if(che()) return 0;}printf("-1");
    69 }
    View Code
  • 相关阅读:
    《勇敢的心》
    笔记本要来啦
    DataSet学习笔记
    俺终于可以回家了
    没有事做,好无聊
    TSQL语句实现清空数据库数据的代码,保留原有表形式和各种约束
    查询重复数据的SQL语句
    DataTable详解
    索引使用大全
    char和byte的转换
  • 原文地址:https://www.cnblogs.com/yyc-jack-0920/p/10671805.html
Copyright © 2020-2023  润新知