Solution

注意到这一题并不要求字符串最短或者是字典序最小, 因此直接构造就可以了. 我们对于每个点\(u \ne 0\)找到一个串\(S\), 使得\(T(u, S) = T(0, S)\), 时间复杂度为\(O(n^3m)\). 假如我们发现对于某个点无法找到一个这样的串, 则说明无解. 接着我们用一个集合来表示自动机中所有点. 对于每个非零的点, 我们用前面求出来的串将其变成\(0\), 同时用这个串更新集合中的其他节点即可. 总时间复杂度: \(O(n^4 + n^3m)\)

#include <cstdio>
#include <cctype>
#include <cstring> namespace Zeonfai
{
inline int getInt()
{
int a = 0, sgn = 1;
char c;
while(! isdigit(c = getchar())) if(c == '-') sgn *= -1;
while(isdigit(c)) a = a * 10 + c - '0', c = getchar();
return a * sgn;
}
}
const int N = 100, M = 26;
int n, m;
struct automaton
{
struct node
{
int edg[M], pth[N * N], len;
}nd[N];
inline void addEdge(int u, int c, int v)
{
nd[u].edg[c] = v;
}
int vis[N][N], flg;
void DFS(int u, int v, int len, int S)
{
vis[u][v] = 1;
if(! u && ! v)
{
flg = 1; nd[S].len = len;
return;
}
for(int i = 0; i < m; ++ i) if(! flg && ! vis[nd[u].edg[i]][nd[v].edg[i]]) nd[S].pth[len] = i, DFS(nd[u].edg[i], nd[v].edg[i], len + 1, S);
}
void getAnswer()
{
for(int i = 1; i < n; ++ i)
{
memset(vis, 0, sizeof(vis));
flg = 0; nd[i].len = -1;
DFS(0, i, 0, i);
if(nd[i].len == -1)
{
puts("[impossible]");
return;
}
}
static int stt[N];
for(int i = 0; i < n; ++ i) stt[i] = i;
while(1)
{
int p = 0;
for(; p < n; ++ p) if(stt[p]) break;
if(p == n) break;
for(int i = 0; i < nd[stt[p]].len; ++ i) putchar('a' + nd[stt[p]].pth[i]);
for(int i = 0; i < n; ++ i) if(stt[i] && i ^ p) for(int j = 0; j < nd[stt[p]].len; ++ j) stt[i] = nd[stt[i]].edg[nd[stt[p]].pth[j]];
stt[p] = 0;
}
}
}G;
int main()
{ #ifndef ONLINE_JUDGE freopen("automaton.in", "r", stdin);
freopen("automaton.out", "w", stdout); #endif using namespace Zeonfai;
n = getInt(), m = getInt();
for(int i = 0; i < n; ++ i) for(int j = 0; j < m; ++ j) G.addEdge(i, j, getInt());
G.getAnswer();
}

2016北京集训测试赛(七)Problem A: 自动机的更多相关文章

  1. 2016北京集训测试赛(十七)Problem C: 数组

    Solution 线段树好题. 我们考虑用last[i]表示\(i\)这个位置的颜色的上一个出现位置. 考虑以一个位置\(R\)为右端点的区间最远能向左延伸到什么位置: \(L = \max_{i \ ...

  2. 2016北京集训测试赛(十七)Problem B: 银河战舰

    Solution 好题, 又是长链剖分2333 考虑怎么统计答案, 我场上的思路是统计以一个点作为结尾的最长上升链, 但这显然是很难处理的. 正解的方法是统计以每个点作为折弯点的最长上升链. 具体的内 ...

  3. 2016北京集训测试赛(十七)Problem A: crash的游戏

    Solution 相当于要你计算这样一个式子: \[ \sum_{x = 0}^m \left( \begin{array}{} m \\ x \end{array} \right) \left( \ ...

  4. 2016北京集训测试赛(十六)Problem C: ball

    Solution 这是一道好题. 考虑球体的体积是怎么计算的: 我们令\(f_k(r)\)表示\(x\)维单位球的体积, 则 \[ f_k(1) = \int_{-1}^1 f_{k - 1}(\sq ...

  5. 2016北京集训测试赛(十六)Problem B: river

    Solution 这题实际上并不是构造题, 而是一道网络流. 我们考虑题目要求的一条路径应该是什么样子的: 它是一个环, 并且满足每个点有且仅有一条出边, 一条入边, 同时这两条边的权值还必须不一样. ...

  6. 2016北京集训测试赛(十六)Problem A: 任务安排

    Solution 这道题告诉我们, 不能看着数据范围来推测正解的时间复杂度. 事实证明, 只要常数足够小, \(5 \times 10^6\)也是可以跑\(O(n \log n)\)算法的!!! 这道 ...

  7. BZOJ 4543 2016北京集训测试赛(二)Problem B: thr 既 长链剖分学习笔记

    Solution 这题的解法很妙啊... 考虑这三个点可能的形态: 令它们的重心为距离到这三个点都相同的节点, 则其中两个点分别在重心的两棵子树中, 且到重心的距离相等; 第三个点可能在重心的一棵不同 ...

  8. 2016北京集训测试赛(十四)Problem B: 股神小D

    Solution 正解是一个\(\log\)的link-cut tree. 将一条边拆成两个事件, 按照事件排序, link-cut tree维护联通块大小即可. link-cut tree维护子树大 ...

  9. 2016北京集训测试赛(十四)Problem A: 股神小L

    Solution 考虑怎么卖最赚钱: 肯定是只卖不买啊(笑) 虽然说上面的想法很扯淡, 但它确实能给我们提供一种思路, 我们能不买就不买; 要买的时候就买最便宜的. 我们用一个优先队列来维护股票的价格 ...

随机推荐

  1. CodeForces 781E Andryusha and Nervous Barriers 线段树 扫描线

    题意: 有一个\(h \times w\)的矩形,其中有\(n\)个水平的障碍.从上往下扔一个小球,遇到障碍后会分裂成两个,分别从障碍的两边继续往下落. 如果从太高的地方落下来,障碍会消失. 问从每一 ...

  2. CodeForces 768E Game of Stones 打表找规律

    题意: 在经典Nim博弈的基础上增加了新的限制:如果从这堆石子中移走\(x\)个石子,那么之后就不能再从这堆移走\(x\)个. 分析: 因为之前的操作会对后面的转移有影响,所以在保存状态时还要记录哪些 ...

  3. git:多个sshkey配置

    克隆项目: 使用git clone +项目.git地址 例如: 创建SSH Key: ssh-keygen -t rsa -C +邮箱地址 sshkey自定义保存:创建后在第二步(enter file ...

  4. Map-Reduce基础

    1.设置文件读入分隔符 默认按行读入; 按句子读入 : conf1.set("textinputformat.record.delimiter", "."); ...

  5. [oldboy-django][2深入django]学生管理(Form)-- 添加(美化Form表单:通过form给前端标签添加属性)

    1 在student_list添加一个a标签, <p><a href="/app01/add_student" class="btn btn-prima ...

  6. poj3083 Children of the Candy Corn BFS&&DFS

    Children of the Candy Corn Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 11215   Acce ...

  7. HEAD DETACHED push origin失败问题

    先说HEAD HEAD是一个头指针,通常情况下指向不同的分支,每个分支对应一个commit(准确的说,每个分支对应多个commit,但是只有一个顶层的commit,而commit之间是简单的线性关系. ...

  8. BZOJ 3771 Triple ——FFT

    直接暴力卷积+统计就可以了. 去重比较复杂. 其实也不复杂,抄吧! 反正AC了. #include <map> #include <cmath> #include <qu ...

  9. linux系统——fread()与read()函数族区别

    fread与read区别: 1,fread是带缓冲的,read不带缓冲. 2,fopen是标准c里定义的,open是POSIX中定义的. 3,fread可以读一个结构.read在linux/unix中 ...

  10. docker (centOS 7) 使用笔记5 - weave网络

    weave官网 https://www.weave.works 1. 下载安装 sudo curl -L git.io/weave -o /usr/local/bin/weave sudo chmod ...