• [BZOJ4945][NOI2017]游戏(2-SAT)


    裸题。对于x地图,强行枚举让它有一个无法行驶,显然只需要枚举'A'和'B'即可。

    没有什么难度,但是如果在考场上区别就会很大,因为2-SAT不是平时常考内容,容易因为逆否命题连边等模板不熟的问题,既耽误时间又拿不到分。

    有几个注意点:

    1.判断一下命题中是否有已经确定不能走的地图,特殊处理。(强制让某个命题i不选(或者强制让命题i'选)的方法是:连边i->i')。

    2.关于输出方案,有一种显然的方法是按缩点后的反向拓扑序遍历,能选则选(让限制尽量宽松)。但是注意到求SCC时得到的强连通块标号实际上已经是反向拓扑序了,所以我们可以直接贪心:对于命题i,如果bel[i]<bel[i'],则选i,否则选i’。

    (上面两个的正确性都只能感性理解。。)

     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<cstring>
     4 #define mem(a) memset(a,0,sizeof(a))
     5 #define rep(i,l,r) for (int i=(l); i<=(r); i++)
     6 using namespace std;
     7 
     8 const int N=100010;
     9 int n,w,m,len,tim,tot,scc,cnt,top,p[N],h[N],to[N<<1],nxt[N<<1];
    10 int ans[N],a[N],stk[N],inq[N],low[N],dfn[N],bel[N];
    11 struct Q{ int u,wu,v,wv; }q[N];
    12 char S[N],ch1,ch2;
    13 void add(int u,int v){ to[++cnt]=v; nxt[cnt]=h[u]; h[u]=cnt; }
    14 
    15 int F(int x,int k){
    16     if (k==1) return x<<1;
    17     if (k==2) { if (a[x]==1) return x<<1; else return (x<<1)|1; }
    18     return (x<<1)|1;
    19 }
    20 
    21 char get(int x,int k){
    22     if (k==1) { if (a[x]==1) return 'B'; else return 'A'; }
    23     if (k==2) { if (a[x]==1 || a[x]==2) return 'C'; else return 'B'; }
    24     return 0;
    25 }
    26 
    27 void tarjan(int x){
    28     dfn[x]=low[x]=++tim; inq[x]=1; stk[++top]=x;
    29     for (int i=h[x],k; i; i=nxt[i])
    30         if (!dfn[k=to[i]]) tarjan(k),low[x]=min(low[x],low[k]);
    31             else if (inq[k]) low[x]=min(low[x],dfn[k]);
    32     if (low[x]==dfn[x]){
    33         scc++; int t;
    34         do { t=stk[top--]; bel[t]=scc; inq[t]=0; }while (t!=x);
    35     }
    36 }
    37 
    38 void jud(){
    39     mem(h); mem(dfn); mem(inq); scc=cnt=top=tim=0;
    40     rep(i,1,m){
    41         int x=F(q[i].u,q[i].wu),y=F(q[i].v,q[i].wv);
    42         if (a[q[i].u]==q[i].wu) continue;
    43         if (a[q[i].v]==q[i].wv) add(x,x^1); else add(x,y),add(y^1,x^1);
    44     }
    45     rep(i,2,(n<<1)|1) if (!dfn[i]) tarjan(i);
    46     int f=0; rep(i,1,n) if (bel[i<<1]==bel[(i<<1)|1]) { f=1; break; }
    47     if (!f){
    48         rep(i,1,n) printf("%c",(bel[i<<1]<bel[(i<<1)|1])?get(i,1):get(i,2));
    49         exit(0);
    50     }
    51 }
    52 
    53 void dfs(int x){
    54     if (x>w){ jud(); return; }
    55     a[p[x]]=1; dfs(x+1); a[p[x]]=2; dfs(x+1);
    56 }
    57 
    58 int main(){
    59     freopen("bzoj4945.in","r",stdin);
    60     freopen("bzoj4945.out","w",stdout);
    61     scanf("%d%d",&n,&w); scanf("%s",S+1); len=strlen(S+1);
    62     rep(i,1,len){
    63         if (S[i]=='a') a[i]=1;
    64         if (S[i]=='b') a[i]=2;
    65         if (S[i]=='c') a[i]=3;
    66         if (S[i]=='x') a[i]=0,p[++tot]=i;
    67     }
    68     scanf("%d",&m);
    69     rep(i,1,m){
    70         scanf("%d %c%d %c",&q[i].u,&ch1,&q[i].v,&ch2);
    71         q[i].wu=ch1-'A'+1; q[i].wv=ch2-'A'+1;
    72     }
    73     dfs(1); puts("-1");
    74     return 0;
    75 }
  • 相关阅读:
    Java.io 包(字节流)
    Java 集合框架(常用数据结构)
    Java.util 包(Date 类、Calendar类、Random类)
    Java.lang 包 (包装类、String类、Math类、Class类、Object类)
    Java 多态(接口)
    maxcompute troubleshoot
    maxcompute
    文件命名
    weblogic修改ServerName
    设计模式---策略模式
  • 原文地址:https://www.cnblogs.com/HocRiser/p/8981446.html
Copyright © 2020-2023  润新知