zoukankan      html  css  js  c++  java
  • BZOJ4945 NOI2017 游戏

    这题放在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("
    ");
    125         return 0;
    126     }
    127     printf("-1
    ");
    128     
    129     return 0;
    130 }
  • 相关阅读:
    【MFC初学】
    【递归】【3月周赛1】【Problem B】
    不管ACM是不是屠龙之技
    【贪心+背包】【HDU2546】【饭卡】
    【精度问题】【HDU2899】Strange fuction
    【泛化物品】【HDU1712】【ACboy needs your help】
    【递推】【HDU2585】【hotel】
    【二进制拆分多重背包】【HDU1059】【Dividing】
    【水:最长公共子序列】【HDU1159】【Common Subsequence】
    【递推+矩阵快速幂】【HDU2604】【Queuing】
  • 原文地址:https://www.cnblogs.com/mollnn/p/8447379.html
Copyright © 2011-2022 走看看