P7123

· · 题解

我们希望用 DFS 搜遍整张图,并模拟类似 Tarjan 的过程,大致有:

更具体地,我们分别考虑当前点 u 走过某个通道到达了 v 为三种点的情况:

在一个点所有 m 条出边都被访问完之后,我们要回溯到其父亲,考虑利用先前算过的 \operatorname {low}_u 做到“返祖”:

然后就完成了 DFS 的过程,注意到每条边我们可能需要走 2n 步,总共 nm 条边,所以至多走 2n^2m=16000 步,可以通过本题。

const int INF = 0x3f3f3f3f;

char str[2][10] = { "left", "right" }, buf[10];
char Pass(int a, char typ, int b) {
    printf("%d %s %d\n", a, str[typ == 'l' ? 0 : 1], b);
    fflush(stdout);
    scanf("%s", buf);
    if(buf[0] == 't') exit(0);
    return buf[0];
}
int Walk(char typ, int x = INF) {
    char cur = typ; int ret = 0;
    for(; cur == typ && ret < x; ++ret) cur = Pass(0, typ, 0);
    return ret;
}

int m, dfv, low_c[30];
int Dfs() {
    int u = ++dfv, low_idx = -1;
    for(int i = 0; i < m; ++i) {
        char ret = Pass(1, 'r', 1);
        int c = 0;
        if(ret == 'c') {
            int v = Dfs();
            c = low_c[v] - 1;
        } else if(ret == 'r') {
            if(Pass(0, 'l', 0) == 'r') {
                c = Walk('r'); Walk('r', c);
            } else {
                c = 0; Pass(0, 'r', 0);
            }
        } else if(ret == 'l') {
            Walk('l'); c = Walk('r') - 1;
            Walk('l'); Walk('r', c);
        }
        if(c > low_c[u]) {
            low_idx = (i + 1) % m;
            low_c[u] = c;
        }
    }
    if(u != 1) {
        char cur = Pass(low_idx, 'l', low_idx);
        if(cur == 'l') Walk('l');
        Walk('r', low_c[u] - 1);
    }
    return u;
}

int main() {
    scanf("%d%s", &m, buf);
    Dfs();
    return 0;
}