`
darren_nizna
  • 浏览: 71167 次
  • 性别: Icon_minigender_1
  • 来自: 长沙
社区版块
存档分类
最新评论

[ZOJ/ZJU][3190][Resource Archiver][AC自动机]

 
阅读更多

给你 n 个串,和 m 个病毒串。要把这 n 个串连起来来,可以重叠,但不能包含 m 个病毒串中的任意一个。求把 n 个串连起来的最小长度。

#include <iostream>
#include <bitset>
#include <cstdio>
#include <cstdlib>
#include <queue>
using namespace std;

int const N= 1010, M= 60010;
int n, m, cnt, bit[15];
char str[N];

struct Trie{
	int next[2];
	int fail, end;
	
	void init(){
		fail= -1; end= 0;
		next[0]= 0; next[1]= 0;
	}
}tb[M];

inline void insert( char* s, int d ){
	int rt= 0;
	while(  *s ){
		int t= *s- '0';
		
		if( tb[rt].next[t]== 0 ){
			tb[++cnt].init();
			tb[rt].next[t]= cnt;
		}
		rt= tb[rt].next[t]; s++;
	}
	tb[rt].end= d;
}

int que[M], head, tail;

void bfs(){
	int q, p;
	head= 0, tail= 0; que[0]= 0;
	
	while( head<= tail ){
		int now= que[head++];
		
		for( int t= 0; t< 2; ++t )
		if( tb[now].next[t] ){
			p= tb[now].next[t]; q= tb[now].fail;
			
			while( q!= -1 && !tb[q].next[t] ) q= tb[q].fail;
			if( q== -1 ) tb[p].fail= 0;
			else tb[p].fail= tb[q].next[t];
			
			que[++tail]= p;
		}
		else{
			q= tb[now].fail;
			while( q!= -1 && !tb[q].next[t] ) q= tb[q].fail;
			if( q== -1 ) tb[now].next[t]= 0;
			else tb[now].next[t]= tb[q].next[t];
		}
	}
}

struct Node{
	int steps, state, node;
	Node(){}
	Node( int x, int y, int z ):
		node( x ), steps(y), state(z) {}
};

bitset<(1<<10)> flag[M];

int solve(){
	queue<Node> q; q.push( Node(0,0,0) );
	
	flag[0][0]= 1;
	while( !q.empty() ){
		Node now= q.front(); q.pop();
		
		for( int t= 0; t< 2; ++t )
		if( tb[ tb[ now.node ].next[t] ].end>= 0 ){
			Node tmp= now;
			
			tmp.node= tb[ now.node ].next[t];
			tmp.steps+= 1;
			
			if( tb[ tmp.node ].end> 0 )
			tmp.state|= bit[ tb[tmp.node].end- 1 ];
			
			if( tmp.state== bit[n]- 1 ) return tmp.steps;
			
			if( flag[ tmp.node ][ tmp.state ] ) continue;
			flag[ tmp.node ][ tmp.state ]= 1;
			
			q.push( tmp );
		}
	}
	
	return -1;
}

int main(){
	for( int i= 0; i<= 10; ++i ) bit[i]= 1<<i;
	
	while( scanf("%d%d",&n,&m)!= EOF ){
		if( n== 0 && m== 0 ) return 0;
		cnt= 0; tb[0].init();
		
		for( int i= 1; i<= n; ++i ){
			scanf("%s", str );
			insert( str, i );
		}
		
		for( int i= 1; i<= m; ++i ){
			scanf("%s", str );
			insert( str, -1 );
		}
		
		bfs();
		for( int i= 0; i<= cnt; ++i ) flag[i].reset();
		
		int ans= 0;
		ans= solve();
		printf("%d\n", ans );
	}
	
	return 0;
}
 
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics