zoukankan      html  css  js  c++  java
  • LOJ#2305. 「NOI2017」游戏

    长这么大这种题不能1A。。

    $n leq 50000$的abcx序列,要你构造同样长一个ABC序列满足:如果这一位是a那就不能填A;如果是b不能填B;如果是c不能填C;否则随意。并满足$m leq 100000$个限制:如果第$i$位填了$p$,那么第$j$位一定要填$q$。$x$个数不超过8.

    这不是2-SAT模板??至于$x$,枚举一下是$a$,是$b$,还是$c$就好了,才怪嘞这样不T死。你想啊,填了$a$不行说明B和C都行不通,那你再找$b$或$c$验证一下A行不行得通不就得了。然后就是2-SAT模板日常写错QAQ

      1 #include<iostream>
      2 #include<cstring>
      3 #include<cstdio>
      4 //#include<math.h>
      5 //#include<set>
      6 //#include<queue>
      7 //#include<bitset>
      8 //#include<vector>
      9 #include<algorithm>
     10 #include<stdlib.h>
     11 using namespace std;
     12 
     13 #define LL long long
     14 int qread()
     15 {
     16     char c; int s=0,f=1; while ((c=getchar())<'0' || c>'9') (c=='-') && (f=-1);
     17     do s=s*10+c-'0'; while ((c=getchar())>='0' && c<='9'); return s*f;
     18 }
     19 
     20 //Pay attention to '-' , LL and double of qread!!!!
     21 
     22 int n,m;
     23 #define maxn 200011
     24 struct Edge{int to,next;}edge[maxn<<1],edge2[maxn<<1]; int first[maxn],le=2,first2[maxn],le2;
     25 void in(int x,int y) {Edge &e=edge[le]; e.to=y; e.next=first[x]; first[x]=le++;}
     26 void in2(int x,int y) {Edge &e=edge2[le2]; e.to=y; e.next=first2[x]; first2[x]=le2++;}
     27 
     28 int tot,Time,top,sta[maxn],bel[maxn],dfn[maxn],low[maxn],opp[maxn],cho[maxn],du[maxn],que[maxn],head,tail;
     29 bool insta[maxn];
     30 void tarjan(int x)
     31 {
     32     dfn[x]=low[x]=++Time;
     33     sta[++top]=x; insta[x]=1;
     34     for (int i=first[x];i;i=edge[i].next)
     35     {
     36         Edge &e=edge[i];
     37         if (!dfn[e.to]) tarjan(e.to),low[x]=min(low[x],low[e.to]);
     38         else if (insta[e.to]) low[x]=min(low[x],dfn[e.to]);
     39     }
     40     if (dfn[x]==low[x])
     41     {
     42         tot++;
     43         while (sta[top]!=x) insta[sta[top]]=0,bel[sta[top]]=tot,top--;
     44         insta[sta[top]]=0,bel[sta[top]]=tot,top--;
     45     }
     46 }
     47 void tag(int x)
     48 {
     49     cho[x]=2;
     50     for (int i=first2[x];i;i=edge2[i].next)
     51     {
     52         Edge &e=edge2[i];
     53         if (!cho[e.to]) tag(e.to);
     54     }
     55 }
     56 
     57 void clear()
     58 {
     59     memset(first,0,sizeof(first)); le=2;
     60     memset(first2,0,sizeof(first2)); le2=2;
     61     tot=Time=top=0;
     62     memset(bel,0,sizeof(bel));
     63     memset(dfn,0,sizeof(dfn));
     64     memset(low,0,sizeof(low));
     65     memset(opp,0,sizeof(opp));
     66     memset(cho,0,sizeof(cho));
     67     memset(du,0,sizeof(du));
     68 }
     69 
     70 char s[maxn]; int pos[11],lp=0;
     71 struct Eve{int x1,y1,x2,y2;}eve[maxn];
     72 int pp[maxn][2];
     73 
     74 int getnum(char c) {return c=='A'?0:(c=='B'?1:2);}
     75 char getch(int x) {return x==0?'A':(x==1?'B':'C');}
     76 
     77 bool END;
     78 bool work()
     79 {
     80 //    cout<<(s+1)<<endl;
     81     clear();
     82     for (int i=1;i<=n;i++) if (s[i]=='a') {pp[i][0]=1; pp[i][1]=2;}
     83     else if (s[i]=='b') {pp[i][0]=0; pp[i][1]=2;}
     84     else if (s[i]=='c') {pp[i][0]=0; pp[i][1]=1;}
     85     for (int i=1;i<=m;i++)
     86     {
     87         int x=eve[i].x1,y=eve[i].x2,xx=eve[i].y1,yy=eve[i].y2;
     88         for (int j=0;j<=1;j++) if (pp[x][j]==xx)
     89         {
     90             bool flag=0;
     91             for (int k=0;k<=1;k++) if (pp[y][k]==yy) in(x+j*n,y+k*n),in(y+(k^1)*n,x+(j^1)*n),flag=1;
     92             if (!flag) in(x+j*n,x+(j^1)*n);
     93         }
     94     }
     95 //    for (int i=1;i<=4;i++)
     96 //        for (int j=first[i];j;j=edge[j].next)
     97 //            cout<<i<<' '<<edge[j].to<<endl;cout<<endl;
     98     
     99     for (int i=1;i<=2*n;i++) if (!dfn[i]) tarjan(i);
    100     for (int i=1;i<=n;i++) if (bel[i]==bel[i+n]) return 0;
    101     
    102     for (int i=1;i<=n;i++) opp[bel[i]]=bel[i+n],opp[bel[i+n]]=bel[i];
    103     for (int i=1;i<=2*n;i++)
    104         for (int j=first[i];j;j=edge[j].next)
    105         {
    106             Edge &e=edge[j];
    107             if (bel[i]!=bel[e.to]) in2(bel[e.to],bel[i]),du[bel[i]]++;
    108         }
    109 //    for (int i=1;i<=4;i++) cout<<bel[i]<<' ';cout<<endl;
    110     head=tail=1;
    111     for (int i=1;i<=tot;i++) if (!du[i]) que[tail++]=i;
    112     while (head!=tail)
    113     {
    114         int u=que[head++],v=opp[u];
    115         if (!cho[u]) {cho[u]=1; tag(v);}
    116         for (int i=first2[u];i;i=edge2[i].next)
    117         {
    118             Edge &e=edge2[i];
    119             du[e.to]--; if (!du[e.to]) que[tail++]=e.to;
    120         }
    121     }
    122     for (int i=1;i<=n;i++) if (cho[bel[i]]==1) putchar(getch(pp[i][0])); else putchar(getch(pp[i][1]));
    123     return 1;
    124 }
    125 
    126 void dfs(int x)
    127 {
    128     if (END) return;
    129     if (x>lp) {if (work()) END=1; return;}
    130     s[pos[x]]='a'; dfs(x+1); if (END) return;
    131     s[pos[x]]='b'; dfs(x+1);
    132 }
    133 
    134 int main()
    135 {
    136     n=qread(); lp=qread(); lp=0;
    137     scanf("%s",s+1);
    138     m=qread(); for (int i=1;i<=m;i++)
    139     {
    140         eve[i].x1=qread();
    141         char c; while ((c=getchar())<'A' || c>'Z');
    142         eve[i].y1=getnum(c);
    143         eve[i].x2=qread();
    144         while ((c=getchar())<'A' || c>'Z');
    145         eve[i].y2=getnum(c);
    146     }
    147     for (int i=1;i<=n;i++) if (s[i]=='x') pos[++lp]=i;
    148     dfs(1);
    149     if (!END) puts("-1");
    150     return 0;
    151 }
    View Code
  • 相关阅读:
    吃甘蔗(中等,模拟)
    jquery对象里面的context参数
    event对象的使用注意事项
    EcmaScript源码
    对js运算符“||”和“&&”的总结
    浏览器滚动条样式
    浏览器的重绘与重排
    input[checkbox],input[radiobox]的一些问题
    height:100%
    Sublime Text 3 多行游标
  • 原文地址:https://www.cnblogs.com/Blue233333/p/9231390.html
Copyright © 2011-2022 走看看