zoukankan      html  css  js  c++  java
  • [HNOI2019] 校园旅行 —— 一个边界数据

    https://www.luogu.com.cn/problem/P5292

    考虑如下数据:

    9 9 1
    101011101
    1 2
    2 3
    3 4
    1 4
    4 5
    5 6
    6 7
    7 8
    8 9
    1 9
    

    它询问下图中\(1\)\(9\)是否有回文串:

    其中括号里的是颜色,括号外的是节点编号,加黑的点是一个回文串。

    如果按题解里的算法,建出来的图是这样的:(不信可以随便用一个AC代码试试看——如果懒的自己改可以看文末附的代码)

    看似原来的回文串被破坏了,会输出NO,但其实\(1\)\(9\)之间还存在一个新的回文串10101110101

    \[1\to2\to3\to4\to5\to6\to7\to8\to7\to8\to9 \]

    答案仍然是YES,是正确的!这是因为\(1-0\)边也可以反复经过,可以将\(1-0\)扩展成\(1-0-1-0-\dots-1-0\),原本的回文串依然可以变为新的回文串。

    实验代码

    #include "bits/stdc++.h"
    #define N 5005
    using namespace std;
    int n, m, p, l = 1, r, c[N], fa[N];
    char str[N], f[N][N];
    struct Node {
        int x, y;
    } q[N * N];
    vector<int>g[N], G[N];
    inline int getf(int x) {
        return x == fa[x] ? x : fa[x] = getf(fa[x]);
    }
    void A(int x, int y) {
        f[x][y] = f[y][x] = 1, q[++r] = {min(x, y), max(x, y)};
    }
    inline char dfs(int x, int C) {
        char res = 0;
        c[x] = C;
    
        for (int y : g[x])
            if (c[y] == -1)
                G[x].push_back(y), G[y].push_back(x), res |= dfs(y, C ^ 1), A(x, y);
            else if (c[y] == C)
                res = 1;
    
        return res;
    }
    int main(void) {
    	freopen("a.in", "r", stdin);
    	freopen("a.out", "w", stdout);
        int i, x, y, a, b;
        scanf("%d%d%d%s", &n, &m, &p, str + 1);
    
        for (i = 1; i <= n; ++i)
            fa[i] = i;
    
        for (i = 1; i <= m; ++i) {
            scanf("%d%d", &x, &y);
    
            if (str[x] == str[y])
                g[x].push_back(y), g[y].push_back(x);
            else {
                if ((a = getf(x)) ^ (b = getf(y)))
                    fa[a] = b, G[x].push_back(y), G[y].push_back(x);
            }
        }
    
        for (i = 1; i <= n; ++i)
            c[i] = -1;
    
        for (i = 1; i <= n; ++i) {
            if (c[i] == -1 && dfs(i, 0))
                G[i].push_back(i);
    
            A(i, i);
        }
    
    	for (int i = 1; i <= n; ++i) {
    		for (int j: G[i]) if (j >= i) {
    			printf("%d %d\n", i, j);
    		}
    	}
    
        while (l <= r) {
            x = q[l].x, y = q[l].y, ++l;
    
            for (int a : G[x])
                for (int b : G[y]) {
    //				printf("%d %d->%d %d\n", x, y, a, b);
                    if (str[a] == str[b] && !f[a][b])
                        A(a, b);
    			}
        }
    
        while (p--)
            scanf("%d%d", &x, &y), puts(f[x][y] ? "YES" : "NO");
    
        return 0;
    }
    
  • 相关阅读:
    【docker】win10安装docker教程
    【大数据】hive 删除临时文件 .hive-staging_hive
    【PostgreSql】生成数据字典
    【python3】基于scrapyd + scrapydweb 的可视化部署
    【python3】将视频转换为代码视频
    博客转移,永久退出博客园
    对dataframe中某一列进行计数
    解决mac上matplotlib中文无法显示问题
    在Jupyter notebook中使用特定虚拟环境中的python的kernel
    ubuntu18.04里更新系统源和pip源
  • 原文地址:https://www.cnblogs.com/frank3215/p/14986419.html
Copyright © 2011-2022 走看看