zoukankan      html  css  js  c++  java
  • LOJ6036 「雅礼集训 2017 Day4」 编码 2-SAT、Trie

    传送门


    每个串只有一个??还只能填0或者1,不难想到2-SAT求解。

    一个很暴力的想法是枚举?0或者1,然后对所有可能的前缀连边。这样边数是(O(n^2))的,需要优化。

    看到前缀不难想到Trie树。将所有串的所有可能形态填入Trie树中,然后使用前缀后缀优化2-SAT连边的方式优化连边。

    具体来说对于每一个串开两个点表示?0还是1,对于Trie树上每一个串的结束节点也开两个点,表示这个点及其所有前缀中是否存在已经选过的串。

    连边考虑一些互为前缀的串。设串为(s_1,s_2,s_3,...,s_k),第(i)个串在Trie树上的节点的(01)变量为(bool[i][0/1]),第(i)个节点对应串的(01)变量为(belong[i][0/1])(为了好描述,这里定义的(belong[i][0/1])表示第(i)个串填入01之后是否得到当前串,是为(1)

    那么有边

    (belong[i][1] ightarrow bool[i][1])

    (bool[i][0] ightarrow bool[i -1][0])

    (bool[i][1] ightarrow bool[i + 1][1])

    (bool[i][0] ightarrow belong[i][0])

    (bool[i][1] ightarrow belong[i + 1][0])

    这些边可以在建Trie的过程中直接建。记得要建逆否命题的边。然后跑一遍缩点就行了

    细节:①开始要将字符串按长度从小到大排序,才可以保证上面方法的正确性;②可能存在某些串相等,建Trie的时候要特别注意。

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<ctime>
    #include<algorithm>
    #include<cstring>
    #include<iomanip>
    #include<queue>
    #include<vector>
    #define INF 0x3f3f3f3f
    //This code is written by Itst
    using namespace std;
    
    const int MAXN = 3e6 + 3;
    struct Edge{
    	int end , upEd;
    }Ed[MAXN << 3];
    int head[MAXN] , N , cntN = 1 , cntEd;
    
    inline void addEd(int a , int b){
    	Ed[++cntEd] = (Edge){b , head[a]};
    	head[a] = cntEd;
    }
    
    namespace Trie{
    	int ch[MAXN][2] , ind[MAXN] , cnt = 1;
    
    	void insert(string s , int bl){
    		int cur = 1 , up = 0;
    		for(auto c : s){
    			if(!ch[cur][c - '0'])
    				ch[cur][c - '0'] = ++cnt;
    			cur = ch[cur][c - '0'];
    			if(ind[cur]) up = ind[cur];
    		}
    		cntN += 2;
    		addEd(bl , cntN); addEd(cntN ^ 1 , bl ^ 1);
    		if(up){
    			addEd(up , cntN); addEd(cntN ^ 1 , up ^ 1);
    			addEd(up , bl ^ 1); addEd(bl , up ^ 1);
    		}
    		ind[cur] = cntN;
    	}
    }
    using Trie::insert;
    
    int stk[MAXN] , dfn[MAXN] , low[MAXN] , in[MAXN];
    int top , ts , cntSCC;
    bool vis[MAXN] , ins[MAXN];
    
    void pop(int x){
    	++cntSCC;
    	do{
    		in[stk[top]] = cntSCC;
    		ins[stk[top]] = 0;
    	}while(stk[top--] != x);
    }
    
    void tarjan(int x , int p){
    	vis[x] = ins[x] = 1;
    	stk[++top] = x;
    	dfn[x] = low[x] = ++ts;
    	for(int i = head[x] ; i ; i = Ed[i].upEd){
    		if(!vis[Ed[i].end]) tarjan(Ed[i].end , x);
    		else if(!ins[Ed[i].end]) continue;
    		low[x] = min(low[x] , low[Ed[i].end]);
    	}
    	if(dfn[x] == low[x]) pop(x);
    }
    
    vector < string > str;
    
    bool cmp(string a , string b){return a.size() < b.size();}
    
    int main(){
    #ifndef ONLINE_JUDGE
    	freopen("in","r",stdin);
    	//freopen("out","w",stdout);
    #endif
    	cin >> N;
    	for(int i = 1 ; i <= N ; ++i){
    		string s;
    		cin >> s;
    		str.push_back(s);
    	}
    	sort(str.begin() , str.end() , cmp);
    	for(auto t : str){
    		cntN += 2;
    		int nd = cntN , pos = t.find('?');
    		if(pos != string::npos){
    			t[pos] = '0';
    			insert(t , nd - 1);
    			t[pos] = '1';
    			insert(t , nd);
    		}
    		else{
    			insert(t , nd);
    			addEd(nd - 1 , nd);
    		}
    	}
    	for(int i = 2 ; i <= cntN ; ++i)
    		if(!vis[i]) tarjan(i , 0);
    	for(int i = 2 ; i <= cntN ; i += 2)
    		if(in[i] == in[i + 1])
    			return puts("NO") , 0;
    	puts("YES");
    	return 0;
    }
    
  • 相关阅读:
    PHP调用WCF提供的方法
    关于git报 warning: LF will be replaced by CRLF in README.md.的警告的解决办法
    vue中引入mui报Uncaught TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them的错误
    微信小程序报Cannot read property 'setData' of undefined的错误
    Vue那些事儿之用visual stuido code编写vue报的错误Elements in iteration expect to have 'v-bind:key' directives.
    关于xampp中无法启动mysql,Attempting to start MySQL service...的解决办法!!
    PHP的环境搭建
    新手PHP连接MySQL数据库出问题(Warning: mysqli_connect(): (HY000/1045): Access denied for user 'root'@'localhost' (using password: YES))
    手机号码、获得当前时间,下拉框,填写限制
    团队作业(五):冲刺总结
  • 原文地址:https://www.cnblogs.com/Itst/p/10467861.html
Copyright © 2011-2022 走看看