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;
    }
    
  • 相关阅读:
    hdu 1017 A Mathematical Curiosity 解题报告
    hdu 2069 Coin Change 解题报告
    hut 1574 组合问题 解题报告
    hdu 2111 Saving HDU 解题报
    hut 1054 Jesse's Code 解题报告
    hdu1131 Count the Trees解题报告
    hdu 2159 FATE 解题报告
    hdu 1879 继续畅通工程 解题报告
    oracle的系统和对象权限
    oracle 自定义函数 返回一个表类型
  • 原文地址:https://www.cnblogs.com/frank3215/p/14986419.html
Copyright © 2011-2022 走看看