BZOJ4945 NOI2017 游戏 - 2-SAT

这题放在NOI里应该不算难的吧……但是细节比较多,所以写起来会有点**

题目限定了道路不能通行某种车辆,也就是可以通行两种车辆

我们将这两种车辆分别作为正点和反点进行约束就可以了

建图较为容易

最后将所有的x枚举一下即可

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <algorithm>
  5 #include <vector>
  6 #include <cstdlib>
  7 
  8 using namespace std;
  9 
 10 vector <int> g[100005];
 11 vector <int> sta;
 12 vector <int> pos;
 13 int compcnt = 0;
 14 vector <int> comp[100005];
 15 
 16 int dfn[100005], low[100005], is[100005], ic[100005], idx, cnt, n, m, indeg[100005], ans;
 17 
 18 int seq[100005], lim[100005][5], d;
 19 
 20 char str[100005];
 21 
 22 void tarjan(int u) {
 23     is[u] = 2;
 24     low[u] = dfn[u] = ++idx;
 25     sta.push_back(u);
 26     for (int i = 0; i < g[u].size(); i++) {
 27         if (is[g[u][i]] == 0) {
 28             tarjan(g[u][i]);
 29             low[u] = min(low[u], low[g[u][i]]);
 30         }
 31         else {
 32             if (is[g[u][i]] == 2) {
 33                 low[u] = min(low[u], dfn[g[u][i]]);
 34             }
 35         }
 36     }
 37     if (low[u] == dfn[u]) {
 38         ++cnt;
 39         for (int j = 0; j != u;) {
 40             j = sta[sta.size() - 1];
 41             sta.pop_back();
 42             is[j] = 1;
 43             ic[j] = cnt;
 44             comp[cnt].push_back(j);
 45         }
 46     }
 47 }
 48 
 49 bool check() {
 50     for(int i=2;i<=2*n+2;i+=2) {
 51         if(ic[i]==ic[i-1]&&ic[i]) {
 52             return false;
 53         }
 54     }
 55     return true;
 56 }
 57 
 58 inline void link(int p,int q){
 59     
 60     g[p].push_back(q);
 61 }
 62 
 63 int frow(int typ,int key){
 64     if(typ==1) return key==2;
 65     if(typ==2) return key==1;
 66     if(typ==3) return key==1;
 67 }
 68 
 69 int main()
 70 {
 71     scanf("%d%d",&n,&d);
 72     
 73     scanf("%s",&str);
 74     
 75     for (int i=1;i<=n;i++) seq[i]=(str[i-1]=='x'?0:(str[i-1]-'a'+1));
 76     for (int i=1;i<=n;i++) if(seq[i]==0) pos.push_back(i);
 77     
 78     scanf("%d", &m);
 79     
 80     char c1[2],c2[2];
 81     
 82     for (int i=1;i<=m;i++) {
 83         scanf("%d%s%d%s",&lim[i][0],&c1,&lim[i][2],&c2);
 84         lim[i][1]=c1[0]-'A'+1;
 85         lim[i][3]=c2[0]-'A'+1;
 86 
 87     }
 88     
 89     for (int pix=0;pix<1<<d;pix++) {
 90         memset(dfn,0,sizeof dfn); memset(low,0,sizeof low); memset(is,0,sizeof is); memset(ic,0,sizeof ic); 
 91         sta.clear(); 
 92         for(int i=1;i<=cnt;i++) comp[i].clear();
 93         idx=0; cnt=0;
 94 
 95         int tmp = pix;
 96         
 97         for (int i=0;i<2*n+2;i++) g[i].clear();
 98  
 99         for (int j=pos.size()-1;j>=0;j--) {
100             seq[pos[j]]=tmp%2 + 1;
101             tmp/=2;
102         }
103         
104         for (int i=1;i<=m;i++) { 
105             if (lim[i][1]==seq[lim[i][0]]) continue;
106             if (lim[i][3]==seq[lim[i][2]]) link(2*lim[i][0]-frow(seq[lim[i][0]],lim[i][1]),2*lim[i][0]-1+frow(seq[lim[i][0]],lim[i][1]));
107             else link(2*lim[i][0]-frow(seq[lim[i][0]],lim[i][1])
108                      ,2*lim[i][2]-frow(seq[lim[i][2]],lim[i][3])),
109                       link(2*lim[i][2]-1+frow(seq[lim[i][2]],lim[i][3]),
110                            2*lim[i][0]-1+frow(seq[lim[i][0]],lim[i][1]));    
111 
112         }
113         for (int i = 1; i <= 2*n; i++) {
114             if (dfn[i] == 0)
115                 tarjan(i);
116         }
117         
118         if(!check()) continue;
119         for (int i=1;i<=2*n;i+=2) {
120             if(ic[i]<ic[i+1]) 
121                 printf("%c",'A'-'a'+(seq[i/2+1]==1?'b':'a'));    
122             else printf("%c",'A'-'a'+(seq[i/2+1]==3?'b':'c'));
123         }
124         printf("\n");
125         return 0;
126     }
127     printf("-1\n");
128     
129     return 0;
130 }

 

转载于:https://www.cnblogs.com/mollnn/p/8447379.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值