• [并查集][二分图][广搜]luogu P5292 [HNOI2019]校园旅行


    题面

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

    问在无向图中某点对是否有边权组合为01回文串的路径

    分析

    考虑暴力,就是往队列里加入路径的首尾(一个0/1或者两个0/1),BFS扩展

    复杂度 O(m^2)

    可以发现因为可以走非简单路径,可以通过绕同一条边来获得长度一致的部分,所以能否到达只跟图的奇偶性有关

    考虑图论中奇偶性相关的,显然有二分图:奇偶性不变

    那么我们独立考虑0-0边,1-1边,0-1边,把原图割为三个图

    如果是二分图,不难证明只需要保留该二分图的一个生成树,也能保证奇偶性不变

    如果不是二分图,考虑在建立生成树之后加入一个自环,因为如果不是二分图,那么图中必然存在奇环改变了奇偶性,我们加入一个自环来调整这个奇偶性即可

    最后因为要么建立了生成树,要么是生成树加一个自环,所以边数级别是 O(n) ,复杂度降到 O(n^2)

    代码

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <queue>
    using namespace std;
    const int N=5e3+10;
    const int M=5e5+10;
    struct Graph {
        int v,nx;
    }g[2*M+N];
    int cnt,list[N],u[M],v[M],bel[N],inbi[N],f[N][2];
    bool col[N],w[N],vis[N][N];
    int n,m,Q;
    char s[N];
    struct Path {
        int u,v;
    };
    queue<Path> q;
    
    inline int read(){
        register int s=0,w=1;
        char ch=getchar();
        while(ch<'0'||ch>'9') {if(ch=='-')w=-1;ch=getchar();}
        while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
        return s*w;
    }
    
    inline void Add(int u,int v) {g[++cnt]=(Graph){v,list[u]};list[u]=cnt;}
    
    inline int Get_F(int x,int id) {return x==f[x][id]?x:f[x][id]=Get_F(f[x][id],id);}
    
    inline void DFS(int u) {
        for (register int i=list[u];i;i=g[i].nx)
            if (!bel[g[i].v]) col[g[i].v]=col[u]^1,bel[g[i].v]=bel[u],DFS(g[i].v);
            else if (col[g[i].v]==col[u]) inbi[bel[u]]=1;
    }
    
    inline void BFS() {
        while (!q.empty()) {
            register Path now=q.front();q.pop();
            for (register int i=list[now.u];i;i=g[i].nx)
                for (register int j=list[now.v];j;j=g[j].nx)
                    if (!vis[g[i].v][g[j].v]&&w[g[i].v]==w[g[j].v])
                        vis[g[i].v][g[j].v]=vis[g[j].v][g[i].v]=1,q.push((Path){g[i].v,g[j].v});
        }
    }
    
    int main() {
        n=read();m=read();Q=read();
        scanf("%s",s+1);
        for (register int i=1;i<=n;i++) w[i]=s[i]-'0',f[i][0]=f[i][1]=i,vis[i][i]=1,q.push((Path){i,i});
        for (register int i=1;i<=m;i++) {
            u[i]=read();v[i]=read();
            if (w[u[i]]==w[v[i]]) Add(u[i],v[i]),Add(v[i],u[i]);
        }
        for (register int i=1;i<=n;i++) if (!bel[i]) DFS(bel[i]=i);
        cnt=0;memset(list,0,sizeof list);
        for (register int i=1,x,y;i<=m;i++) {
            register bool tp=(w[u[i]]^w[v[i]]);
            if ((x=Get_F(u[i],tp))==(y=Get_F(v[i],tp))) continue;
            f[x][tp]=y;Add(u[i],v[i]);Add(v[i],u[i]);
            if (!tp) vis[u[i]][v[i]]=vis[v[i]][u[i]]=1,q.push((Path){u[i],v[i]});
        }
        for (register int i=1;i<=n;i++) if (inbi[i]) inbi[i]=0,Add(i,i);
        BFS();
        for (register int i=1,x,y;i<=Q;i++) x=read(),y=read(),printf(vis[x][y]?"YES
    ":"NO
    ");
    }
    View Code
    在日渐沉没的世界里,我发现了你。
  • 相关阅读:
    挖矿病毒入侵-分析总结
    Linux查看包依赖关系的神器-repoquery分享
    Elasticsearch 字段为空(null)记录查询
    Python 导数 Elasticsearch 元数据到CSV
    基于docker快速构建MySQL主从复制环境
    Redis环境简单部署(集群/双机)
    FTP 脚本 to Shell脚本&bat脚本&python脚本
    专用服务器模式&共享服务器模式
    CentOS 7安装部署ELK 6.2.4-SUCCESS
    zabbix 数据库迁移变更
  • 原文地址:https://www.cnblogs.com/mastervan/p/14578196.html
Copyright © 2020-2023  润新知