zoukankan      html  css  js  c++  java
  • HDU5487 Difference of Languages(BFS)

    题意:给你两个自动机,求出最短的(如果有相同最短的则求出字典序最小的)能被其中一个自动机接收而不能被另外一个自动机接收的字符串。

    一看是自动机以为是神题,后来比赛最后才有思路。

    两个自动机的状态都是小于1000的,所以可以建一个图,每个结点(u,v)表示当前处于自动机1的状态u和自动机2的状态v,然后相应的这些状态接收[a-z]的字符就会转移到下一个状态。然后从原点(0,0)开始广搜,搜到的第一个accpet[u]!=accept[v]的即是所求的状态。(处理的时候要给每个自动机加一个状态,用来表示失配的时候的情况,这个状态的所有后继都转移向自己,而且本身不是accpet状态,广搜即可)

    #pragma warning(disable:4996)
    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <algorithm>
    #include <vector>
    #include <cmath>
    #include <queue>
    using namespace std;
    
    #define maxn 1005
    
    int n1, m1, k1;
    int n2, m2, k2;
    
    bool tar1[maxn];
    bool tar2[maxn];
    
    int go1[maxn][26];
    int go2[maxn][26];
    
    int prestate[maxn*maxn];
    char prechar[maxn*maxn];
    
    bool vis[maxn*maxn];
    
    bool check(int x)
    {
    	return tar1[x / n2] != tar2[x%n2];
    }
    
    int nextState(int x, int c)
    {
    	return go1[x / n2][c] * n2 + go2[x%n2][c];
    }
    
    int main()
    {
    	int T; cin >> T; int ca = 0;
    	while (T--)
    	{
    		memset(go1, -1, sizeof(go1));
    		memset(go2, -1, sizeof(go2));
    		memset(tar1, 0, sizeof(tar1));
    		memset(tar2, 0, sizeof(tar2));
    
    		int accept;
    		int ui, vi;
    		char ci[3];
    
    		scanf("%d%d%d", &n1, &m1, &k1);
    		for (int i = 0; i < k1; ++i){
    			scanf("%d", &accept);
    			tar1[accept] = true;
    		}
    		for (int i = 0; i < m1; ++i){
    			scanf("%d%d%s", &ui, &vi, ci);
    			go1[ui][ci[0] - 'a'] = vi;
    		}
    		for (int i = 0; i <= n1; ++i){
    			for (int k = 0; k < 26; ++k){
    				if (go1[i][k] == -1) go1[i][k] = n1;
    			}
    		}
    
    		scanf("%d%d%d", &n2, &m2, &k2);
    		for (int i = 0; i < k2; ++i){
    			scanf("%d", &accept);
    			tar2[accept] = true;
    		}
    		for (int i = 0; i < m2; ++i){
    			scanf("%d%d%s", &ui, &vi, ci);
    			go2[ui][ci[0] - 'a'] = vi;
    		}
    		for (int i = 0; i <= n2; ++i){
    			for (int k = 0; k < 26; ++k){
    				if (go2[i][k] == -1) go2[i][k] = n2;
    			}
    		}
    		++n1; ++n2;
    
    		int ans = -1;
    		memset(vis, 0, sizeof(vis));
    		queue<int> Q;
    		Q.push(0);
    		vis[0] = true;
    		while (!Q.empty())
    		{
    			int state = Q.front(); Q.pop();
    			if (check(state)){
    				ans = state;
    				break;
    			}
    			for (int k = 0; k < 26; ++k){
    				int nstate = nextState(state, k);
    				if (!vis[nstate]){
    					Q.push(nstate);
    					vis[nstate] = true;
    					prestate[nstate] = state;
    					prechar[nstate] = k;
    				}
    			}
    		}
    		if (-1 == ans){
    			printf("Case #%d: 0
    ", ++ca);
    			continue;
    		}
    		string ts;
    		while (ans != 0){
    			ts.push_back(char('a' + prechar[ans]));
    			ans = prestate[ans];
    		}
    		reverse(ts.begin(), ts.end());
    		printf("Case #%d: %s
    ", ++ca, ts.c_str());
    	}
    	return 0;
    }
    
  • 相关阅读:
    flannel网络的VXLAN及host-gw
    K8S中Harbor使用Nginx反向代理无法获取image
    kubernetes cluster IP not with in the service CIDR
    supervisor重启服务失败
    Centos系统磁盘目录分析工具-Ncdu
    计算机网络中这些高频考题,你还在死记硬背吗?(三)
    计算机网络中这些高频考题,你还在死记硬背吗?(二)
    计算机网络中这些高频考题,你还在死记硬背吗?(一)
    基于web的图书管理系统设计与实现
    一条贪吃蛇的使命——零基础入门贪吃蛇游戏(附演示地址)
  • 原文地址:https://www.cnblogs.com/chanme/p/4843489.html
Copyright © 2011-2022 走看看