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

    题解

    枚举x所在的地图的颜色,然后2-SAT建边
    如果v所在的地图刚好是不能选的,那么u这边只能选另一种颜色
    否则就是u的颜色到v的颜色
    v的另一种颜色到u的另一种颜色

    代码

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    #include <ctime>
    #include <vector>
    //#define ivorysi
    #define MAXN 100005
    #define eps 1e-7
    #define mo 974711
    #define pb push_back
    using namespace std;
    typedef long long int64;
    typedef unsigned int u32;
    typedef double db;
    int N,D,M;
    char s[MAXN],c[2][MAXN][4],L[MAXN];
    int u[MAXN],v[MAXN];
    struct node {
        int to,next;
    }E[MAXN * 2];
    int head[MAXN * 2],sumE;
    void add(int u,int v) {
        E[++sumE].to = v;
        E[sumE].next = head[u];
        head[u] = sumE;
    }
    int get_id(int u,char c) {
        if(s[u] == 'A') return c == 'B' ? u * 2 : u * 2 + 1;
        if(s[u] == 'B') return c == 'A' ? u * 2 : u * 2 + 1;
        if(s[u] == 'C') return c == 'A' ? u * 2 : u * 2 + 1;
    }
    char get_ch(int u) {
        if(s[u / 2] == 'A') return (u & 1) ? 'C' : 'B';
        if(s[u / 2] == 'B') return (u & 1) ? 'C' : 'A';
        if(s[u / 2] == 'C') return (u & 1) ? 'B' : 'A';
    }
    int sta[MAXN],top,dfn[MAXN],low[MAXN],idx,col[MAXN],tot,instack[MAXN];
    vector<int> ver[MAXN];
    void tarjan(int u) {
        sta[++top] = u;
        dfn[u] = low[u] = ++idx;
        instack[u] = 1;
        for(int i = head[u] ; i ; i = E[i].next) {
    	int v = E[i].to;
    	if(instack[v] == 1) {
    	    low[u] = min(low[u],dfn[v]);
    	}
    	else if(!dfn[v]) {
    	    tarjan(v);
    	    low[u] = min(low[u],low[v]);
    	}
        }
        if(low[u] == dfn[u]) {
    	++tot;
    	while(1) {
    	    int x = sta[top--];
    	    col[x] = tot;
    	    ver[tot].pb(x);
    	    instack[x] = 2;
    	    if(x == u) break;
    	}
        }
    }
    bool check() {
        memset(head,0,sizeof(head));
        sumE = 0;
        for(int i = 1 ; i <= M ; ++i) {
    	if(c[0][i][1] == s[u[i]]) continue;
    	if(c[1][i][1] == s[v[i]]) {
    	    int x = get_id(u[i],c[0][i][1]);
    	    add(x,x ^ 1);
    	}
    	else {
    	    int x = get_id(u[i],c[0][i][1]),y = get_id(v[i],c[1][i][1]);
    	    add(x,y);add(y ^ 1,x ^ 1);
    	}
        }
        for(int i = 1 ; i <= tot ; ++i) ver[i].clear();
        memset(sta,0,sizeof(sta));top = 0;
        memset(dfn,0,sizeof(dfn));idx = 0;
        memset(low,0,sizeof(low));
        memset(col,0,sizeof(col));tot = 0;
        memset(instack,0,sizeof(instack));
        for(int i = 2 ; i <= N * 2 + 1; ++i) {
    	if(!dfn[i]) tarjan(i);
        }
        for(int i = 2 ; i <= N * 2 + 1 ; i += 2) {
    	if(col[i] == col[i ^ 1]) return false;
        }
        memset(L,0,sizeof(L));
        for(int i = 1 ; i <= tot ; ++i) {
    	for(auto k : ver[i]) {
    	    if(!L[k / 2]) {
    		L[k / 2] = get_ch(k);
    	    }
    	}
        }
        return true;
    }
    bool dfs(int dep) {
        if(dep > N) {
    	if(check()) return true;
    	return false;
        }
        if(s[dep] != 'x') {return dfs(dep + 1);}
        else {
    	for(int i = 0 ; i <= 2 ; ++i) {
    	    s[dep] = 'A' + i;
    	    if(dfs(dep + 1)) return true;
    	}
        }
        return false;
    }
    void Init() {
        scanf("%d%d",&N,&D);
        scanf("%s",s + 1);
        for(int i = 1 ; i <= N ; ++i) {
    	if(s[i] != 'x') s[i] = s[i] - 'a' + 'A';
        }
        scanf("%d",&M);
        for(int i = 1 ; i <= M ; ++i) {
    	scanf("%d%s%d%s",&u[i],c[0][i] + 1,&v[i],c[1][i] + 1);
        }
    }
    void Solve() {
        if(!dfs(1)) {puts("-1");return;}
        for(int i = 1 ; i <= N ; ++i) {
    	putchar(L[i]);
        }
        putchar('
    ');
    }
    int main() {
    #ifdef ivorysi
        freopen("f1.in","r",stdin);
    #endif
        Init();
        Solve();
    }
    
  • 相关阅读:
    定理环境
    tcolorbox 宏包简明教程
    【专访】南科大数学系何炳生教授——四十年上下求索
    研究生导师为什么喜欢问学生家境?
    高德纳谈《具体数学》的诞生
    剑桥大学
    线性代数
    APPCAN的mas服务报错
    github删除仓库
    Angular2入门教程-2 实现TodoList App
  • 原文地址:https://www.cnblogs.com/ivorysi/p/9051145.html
Copyright © 2011-2022 走看看