zoukankan      html  css  js  c++  java
  • [BZOJ4945][Noi2017]游戏 2-sat

    对于所有的x,我们枚举他的地图类型,事实上我们只需要枚举前两种地形就可以覆盖所有的情况。

    之后就变成了裸的2-sat问题。

    对于一个限制,我们分类讨论:

    1.h[u]不可选,跳过

    2.h[v]不可选,则h[v]也不可选,将u与u‘连边,表示u不可选。

    3.否则从u向v连边表示选u就必须选v,从u’向v‘连边表示选v'就必须选u’(逆否命题)。

    tarjan缩点判断可行性。

    输出方案按照缩点编号选择编号小的点输出即可(逆序拓扑序)。

      1 #include<iostream>
      2 #include<cstring>
      3 #include<cstdlib>
      4 #include<cstdio>
      5 #include<cmath>
      6 #include<algorithm>
      7 #define maxn 400005
      8 using namespace std;
      9 inline int read() {
     10     int x=0,f=1;char ch=getchar();
     11     for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-1;
     12     for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0';
     13     return x*f;
     14 }
     15 struct Edge {int to,nxt;}e[maxn*2];
     16 int head[maxn],cnt;
     17 void add(int u,int v) {e[cnt].to=v;e[cnt].nxt=head[u];head[u]=cnt++;}
     18 struct Ask {int u,v;char a[10],b[10];}q[maxn];
     19 int n,d,pos[maxn],m;
     20 char s[maxn],cs[maxn];
     21 bool flag=0;
     22 int dfn[maxn],low[maxn],tot,bel[maxn],par[maxn],l[maxn],r[maxn],sta[maxn],top,scc;
     23 bool vis[maxn],inq[maxn];
     24 void init() {
     25     memset(head,-1,sizeof(head));cnt=0;
     26     memset(dfn,0,sizeof(dfn));
     27     memset(low,0,sizeof(low));
     28     memset(bel,0,sizeof(bel));tot=0;scc=0;
     29     memset(vis,0,sizeof(vis));
     30     memset(inq,0,sizeof(inq));
     31 }
     32 void tarjan(int x) {
     33     dfn[x]=low[x]=++tot;sta[++top]=x;inq[x]=1;
     34     for(int i=head[x];i>=0;i=e[i].nxt) {
     35         int to=e[i].to;
     36         if(!dfn[to]) {
     37             tarjan(to);
     38             low[x]=min(low[x],low[to]);
     39         }
     40         else if(inq[to]) {low[x]=min(low[x],dfn[to]);}
     41     }
     42     if(dfn[x]==low[x]) {
     43         scc++;
     44         while(1) {
     45             inq[sta[top]]=0;
     46             bel[sta[top--]]=scc;
     47             if(sta[top+1]==x) break;
     48         }
     49     }
     50 }
     51 int que[maxn],fro,tail,in[maxn];
     52 void work() {
     53     init();
     54     for(int i=1;i<=n;i++) {
     55         int ttmp=0;
     56         if(s[i]=='x') {s[i]=cs[i];ttmp=1;}
     57         if(s[i]=='a') {l[i]=i+n,r[i]=i+n+n;}
     58         if(s[i]=='b') {l[i]=i,r[i]=i+n+n;}
     59         if(s[i]=='c') {l[i]=i,r[i]=i+n;}
     60         if(ttmp==1) s[i]='x';
     61         par[l[i]]=r[i];par[r[i]]=l[i];vis[r[i]]=vis[l[i]]=1;
     62     }
     63     int ql,qr;
     64     for(int i=1;i<=m;i++) {
     65         if(q[i].a[1]=='A') ql=q[i].u;
     66         else if(q[i].a[1]=='B') ql=q[i].u+n;
     67         else ql=q[i].u+n+n;
     68         if(q[i].b[1]=='A') qr=q[i].v;
     69         else if(q[i].b[1]=='B') qr=q[i].v+n;
     70         else qr=q[i].v+n+n;
     71         if(ql==qr) continue;
     72         if(!vis[ql]) continue;
     73         if(!vis[qr]) {
     74             add(ql,par[ql]);
     75             continue;
     76         }
     77         add(ql,qr);add(par[qr],par[ql]);
     78     }
     79     for(int i=1;i<=n+n+n;i++) {if(vis[i]&&!dfn[i]) tarjan(i);}
     80     for(int i=1;i<=n+n+n;i++) {
     81         if(!vis[i]) continue;
     82         if(bel[i]==bel[par[i]]) return;
     83     }
     84     flag=1;
     85     for(int i=1;i<=n;i++) {
     86         int out=0;
     87         if(bel[l[i]]<bel[r[i]]) out=l[i];
     88         else out=r[i];
     89         if(out==i) printf("A");
     90         else if(out==i+n) printf("B");
     91         else printf("C");
     92     }
     93 }
     94 void dfs(int x) {
     95     if(x==d+1) {
     96         work();
     97         if(flag) exit(0);
     98         return;
     99     }
    100     cs[pos[x]]='a';dfs(x+1);
    101     cs[pos[x]]='b';dfs(x+1);
    102 }
    103 int main() {
    104     n=read(),d=read();
    105     scanf("%s",s+1);
    106     for(int i=1;i<=n;i++) {if(s[i]=='x') pos[++pos[0]]=i;}
    107     m=read();
    108     for(int i=1;i<=m;i++) {q[i].u=read();scanf("%s",q[i].a+1);q[i].v=read();scanf("%s",q[i].b+1);}
    109     dfs(1);printf("-1
    ");
    110 } 
    View Code
  • 相关阅读:
    Java 面向对象之static,final,匿名对象,内部类,包,修饰符
    用NotePad++如何实现大小写转换
    Java 面向对象之接口、多态
    Jmeter测试API接口,用Jmeter自动化之检查DB数据
    SQLServer 大小写转换
    vmstat 命令详解
    Java 面向对象之构造方法
    Java 面向对象之继承和重写OverWrite,重写和重载的区别,抽象类
    Java 集合、Iterator迭代器、泛型等
    【已解决】面试测试岗位遇到的几个未解决的问题
  • 原文地址:https://www.cnblogs.com/wls001/p/10154294.html
Copyright © 2011-2022 走看看