zoukankan      html  css  js  c++  java
  • zoj4097 Rescue the Princess无向图缩点有重边+lca

    题目链接:zoj4097 Rescue the Princess

    题意:给一个有可能有重边的无向图,问从v,w到u是否有不相交的路径。

    题解:先边双联通分量缩点就会的得到一片森林,如果不在同一颗树里面肯定,no,在同一颗树里面分情况讨论一下

    #include<bits/stdc++.h>
    #include<set>
    #include<cstdio>
    #include<iomanip>
    #include<iostream>
    #include<string>
    #include<cstring>
    #include<algorithm>
    #define pb push_back
    #define mk make_pair
    #define ll long long
    #define fi first
    #define se second
    #define PI 3.14159265
    #define ls l,m,rt<<1
    #define rs m+1,r,rt<<1|1
    #define eps 1e-7
    #define pii pair<int,int>
    #define pll pair<ll,ll>
    typedef unsigned long long ull;
    const int mod=998244353;
    const ll inf=0x3f3f3f3f3f3f3f;
    const int N=1e5+5;
    using namespace std;
    int n,m,q;
    vector<int>g[N],G[N];
    int dfn[N],low[N],s[N],tot,cmp[N],scc_cnt,ind;
    bool vis[N],ins[N];
    int belong[N];
    int block=0;
    int tarjan(int v,int f,int b)
    {
        low[v]=dfn[v]=++ind;
        s[++tot]=v;
        ins[v]=1;
        vis[v]=1;
        belong[v]=b;
        int flag=0;//判断是否为重边
        for(int to:g[v])
        {
            if(f==to)
            {
                if(++flag<2)continue;//大于等于二时有重边
            }
            if(!dfn[to])
            {
                tarjan(to,v,b);
                low[v]=min(low[v],low[to]);
            }
            else if(ins[v])low[v]=min(low[v],low[to]);
        }
        if(low[v]==dfn[v])
        {
            cmp[v]=++scc_cnt;
            while(s[tot]!=v)ins[s[tot]]=0,cmp[s[tot--]]=scc_cnt;
            ins[v]=0;
            tot--;
        }
    }
    int f[N][18],dep[N];
    void dfs(int v,int fa,int d)
    {
        vis[v]=1;
        f[v][0]=fa;
        dep[v]=d;
        for(int to:G[v])
        {
            if(to==fa)continue;
            dfs(to,v,d+1);
        }
    }
    int lca(int x,int y)
    {
        if(dep[x]<dep[y])swap(x,y);
        int k=dep[x]-dep[y];
        for(int i=0;i<18;i++)
        {
            if((k>>i)&1)x=f[x][i];
        }
        if(x==y)return y;
        for(int i=17;i>=0;i--)
        {
            if(f[x][i]!=f[y][i])
            {
                x=f[x][i];y=f[y][i];
            }
        }
        return f[x][0];
    }
    void init()
    {
        for(int i=0;i<=scc_cnt;i++)
        {
           G[i].clear(); dep[i]=0;
           for(int j=0;j<18;j++)f[i][j]=0;
        }
        for(int i=0;i<=n;i++)vis[i]=low[i]=dfn[i]=0,g[i].clear();
        scc_cnt=0;tot=0;ind=0;block=0;
    }
    int main()
    {
        int T;
        scanf("%d",&T);
        while(T--)
        {
            init();
            scanf("%d %d %d",&n,&m,&q);
            for(int i=0;i<m;i++)
            {
                int x,y;
                scanf("%d %d",&x,&y);
                g[x].pb(y);
                g[y].pb(x);
            }
            for(int i=1;i<=n;i++)
            {
                if(!vis[i])
                {
                    tarjan(i,0,++block);
                }
            }
            for(int i=1;i<=n;i++)
            {
                for(int to:g[i])
                {
                    if(cmp[to]!=cmp[i])
                    {
                        G[cmp[to]].pb(cmp[i]);
                    }
                }
            }
            for(int i=1;i<=scc_cnt;i++)vis[i]=0;
            for(int i=1;i<=scc_cnt;i++)
            {
                if(!vis[i])
                {
                    dfs(i,0,0);
                }
            }
            for(int i=1;i<18;i++)
            {
                for(int j=1;j<=scc_cnt;j++)
                {
                    f[j][i]=f[f[j][i-1]][i-1];
                }
            }
            while(q--)
            {
                int u,v,w;
                scanf("%d %d %d",&u,&v,&w);
                if(belong[u]!=belong[v]||belong[v]!=belong[w]||belong[u]!=belong[w])
                {
                    printf("No
    ");continue;
                }
                u=cmp[u];v=cmp[v];w=cmp[w];
                bool f1=1;
                int uv=lca(u,v),uw=lca(u,w),vw=lca(v,w);
                    if(uv==u)
                    {
                        if(vw==u&&uw==u) ;
                        else if(uw!=u);
                        else f1=0;
                    }
                    else if(uv==v)
                    {
                        if(uw==u);
                        else f1=0;
                    }
                    else
                    {
                        if(uw!=u)f1=0;
                    }
                    if(f1)printf("Yes
    ");
                    else printf("No
    ");
            }
        }
        return 0;
    }
    /*
    1
    2 1 2
    1 2
    1 1 1
    2 1 2
    */
  • 相关阅读:
    ubuntu上virsh+kvm安装虚拟机
    Less(31)GET-BLIND-IMPIDENCED MISMATCH-Having a WAF in front of web application
    Less(26a)GET
    Less(26)Trick with comments and space (过滤了注释和空格的注入)
    Less(30)Get-Blind Havaing with WAF
    Less(29)基于WAF的一个错误
    Less(25a)Trick with OR & AND Blind (过滤了or和and的盲注)
    Less(25)Trick with OR & AND (过滤了or和and)
    Less(24)Second Degree Injections *Real treat* -Store Injections (二次注入)
    Less(23)GET
  • 原文地址:https://www.cnblogs.com/lhclqslove/p/10717149.html
Copyright © 2011-2022 走看看