1. 程式人生 > >BZOJ4945 NOI2017 遊戲 - 2-SAT

BZOJ4945 NOI2017 遊戲 - 2-SAT

tor ios eof clu urn 約束 -s namespace --

這題放在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 }

BZOJ4945 NOI2017 遊戲 - 2-SAT