• [HNOI2019]校园旅行


    题意

    https://www.luogu.org/problemnew/show/P5292


    思考

    最朴素的想法,从可行的二元组(u,v)向外拓展,及u的出边所指的颜色与v的出边所指的颜色若相同,继续更新二元组(u',v'),复杂度约为O(m2)。

    我们发现,很多时候边上的转移其实是没有必要的,因为有很多情况能转移到相同的字符串,因此我们要删去一些边,并且使得不改变原图的性质。

    先考虑原图中边的两端颜色相同的边构成的连通块,若为二分图,则取其任意生成树;若不为二分图,则取其任意生成树,并添加一个自环。

    二分图的意思,就是相同颜色段的长度只与奇偶性有关,当字符串另一端不断添加相同字符的同时,二分图中的字符可以不断地在A集合与B集合中转换。

    两端颜色不同的边构成的连通块,也是取其任意生成树。

    这样边数为O(n)级别,复杂度为O(n2)。


    代码

      1 // luogu-judger-enable-o2
      2 #include<bits/stdc++.h>
      3 using namespace std;
      4 const int maxn=5E5+5;
      5 int head[maxn*2],size,n,m,x,y,color[maxn],flag,q;
      6 char c[maxn];
      7 bool f[5005][5005],can[maxn];
      8 struct edge{int from,to,next;};
      9 struct pt{int x,y;};
     10 queue<pt>Q;
     11 struct graph
     12 {
     13     edge E[maxn*2];
     14     int head[maxn*2],size;
     15     void add(int u,int v)
     16     {
     17         E[++size].to=v;
     18         E[size].next=head[u];
     19         E[size].from=u;
     20         head[u]=size;
     21     }
     22 }A,B,G;
     23 void dfs1(int u,int now)
     24 {
     25     color[u]=now;
     26     for(int i=A.head[u];i;i=A.E[i].next)
     27     {
     28         int v=A.E[i].to;
     29         if(now==color[v])flag=1;
     30         if(color[v])continue;
     31         G.add(u,v);
     32         G.add(v,u);
     33         if(now==1)dfs1(v,2);
     34         else dfs1(v,1);
     35     }
     36 }
     37 void dfs2(int u)
     38 {
     39     color[u]=1;
     40     for(int i=B.head[u];i;i=B.E[i].next)
     41     {
     42         int v=B.E[i].to;
     43         if(color[v])continue;
     44         G.add(u,v);
     45         G.add(v,u);
     46         dfs2(v);
     47     }
     48 }
     49 void init1()
     50 {
     51     for(int i=1;i<=A.size;++i)
     52         can[A.E[i].from]=can[A.E[i].to]=1;
     53     for(int u=1;u<=n;++u)
     54     {
     55         if(color[u]||!can[u])continue;
     56         flag=0;
     57         dfs1(u,1);
     58         if(flag)G.add(u,u);
     59     }
     60 }
     61 void init2()
     62 {
     63     memset(color,0,sizeof(color));
     64     memset(can,0,sizeof(can));
     65     for(int i=1;i<=B.size;++i)
     66         can[B.E[i].from]=can[B.E[i].to]=1;
     67     for(int u=1;u<=n;++u)
     68     {
     69         if(color[u]||!can[u])continue;
     70         dfs2(u);
     71     }
     72 }
     73 void work()
     74 {
     75     while(!Q.empty())
     76     {
     77         pt u=Q.front();
     78         Q.pop();
     79         for(int i=G.head[u.x];i;i=G.E[i].next)
     80         {
     81             for(int j=G.head[u.y];j;j=G.E[j].next)
     82             {
     83                 int u=G.E[i].to,v=G.E[j].to;
     84                 if(c[u]==c[v])
     85                 {
     86                     if(!f[u][v])Q.push((pt){u,v});
     87                     f[u][v]=f[v][u]=1;
     88                 }
     89             }
     90         }
     91     }
     92 }
     93 int main()
     94 {
     95     ios::sync_with_stdio(false);
     96     cin>>n>>m>>q;
     97     for(int i=1;i<=n;++i)
     98     {
     99         cin>>c[i];
    100         f[i][i]=1;
    101         Q.push((pt){i,i});
    102     }
    103     for(int i=1;i<=m;++i)
    104     {
    105         cin>>x>>y;
    106         if(c[x]==c[y])
    107         {
    108             A.add(x,y),A.add(y,x);
    109             f[x][y]=f[y][x]=1;
    110             Q.push((pt){x,y});
    111         }
    112         else B.add(x,y),B.add(y,x);
    113     }
    114     init1();
    115     init2();
    116     work();
    117     for(int i=1;i<=q;++i)
    118     {
    119         cin>>x>>y;
    120         if(f[x][y])cout<<"YES"<<endl;
    121         else cout<<"NO"<<endl;
    122     }
    123     return 0;
    124 }
    View Code
  • 相关阅读:
    课二 计算机硬件组成余下
    课一 计算机硬件组成
    电梯演讲视频
    团队成员个人介绍
    day-65Django
    day-64Django
    day-63Django
    day-62Django
    day-61Django
    day-60Django
  • 原文地址:https://www.cnblogs.com/GreenDuck/p/10710072.html
Copyright © 2020-2023  润新知