zoukankan      html  css  js  c++  java
  • 【强连通分量】Bzoj1194 HNOI2006 潘多拉的盒子

    Description

     

    Sulotion

    首先要对每对咒语机建图,判断机器a是否能生成所有机器b生成的

    如果跑一个相同的串,最后结束的点b可输出a不可输出,判断就为否

    大概就用这种思路,f[x][y]表示a中跑到x b中跑到y是否可行,然后大概记忆化搜索,只有两种转移

    //感觉跑自动机的题目经常要这么(跑到了哪一个结点)表示状态

    建图之后可能会有环(a和b生成的一样),于是强连通分量缩点

    变成了DAG,然后dp记忆化搜索出答案

    Code

    一开始边的数组也直接用maxn了,最近怎么总是犯低级错误

     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<cstring>
     4 using namespace std;
     5 const int maxn=55,maxm=1e4+5;
     6 
     7 int S;
     8 struct box{
     9     int n,m,p[maxn][2],ok[maxn];
    10 }a[maxn];
    11 int head[maxn],e[maxm],nxt[maxm],tot;
    12 int adde(int u,int v){
    13     e[++tot]=v,nxt[tot]=head[u];
    14     head[u]=tot;
    15 }
    16 int low[maxn],pre[maxn],clock;
    17 int scc[maxn],size[maxn],cnt,r[maxn],t;
    18 
    19 int c,d;
    20 int vis[maxn][maxn];
    21 int pd(int x,int y){
    22     if(vis[x][y]) return 1;
    23     if(!a[c].ok[x]&&a[d].ok[y]) return 0;
    24     vis[x][y]=1;
    25     if(!pd(a[c].p[x][0],a[d].p[y][0])) return 0;
    26     if(!pd(a[c].p[x][1],a[d].p[y][1])) return 0;
    27     return 1;
    28 }
    29 
    30 int tarjan(int u){
    31     pre[u]=low[u]=++clock;
    32     r[++t]=u;
    33     for(int i=head[u];i;i=nxt[i]){
    34         int v=e[i];
    35         if(!pre[v]){
    36             tarjan(v);
    37             low[u]=min(low[u],low[v]);
    38         }
    39         else if(!scc[v]){
    40             low[u]=min(low[u],pre[v]);
    41         }
    42     }
    43     if(pre[u]==low[u]){
    44         ++cnt;
    45         while(t){
    46             scc[r[t]]=cnt;
    47             size[cnt]++;
    48             if(r[t--]==u) break;
    49         }
    50     }
    51 }
    52 
    53 int f[maxn],G[maxn][maxn];
    54 int dfs(int u){
    55     if(f[u]) return f[u];
    56     int ret=0;
    57     for(int v=1;v<=cnt;v++)
    58         if(G[u][v]) ret=max(ret,dfs(v));
    59     return f[u]=ret+size[u];
    60 }
    61 
    62 int main(){
    63     int x;
    64     scanf("%d",&S);
    65     for(int k=1;k<=S;k++){
    66         scanf("%d%d",&a[k].n,&a[k].m);
    67         for(int i=1;i<=a[k].m;i++)
    68             scanf("%d",&x),a[k].ok[x+1]=1;
    69         for(int i=1;i<=a[k].n;i++){
    70             scanf("%d%d",&a[k].p[i][0],&a[k].p[i][1]);
    71             a[k].p[i][0]++,a[k].p[i][1]++;
    72         }
    73     }
    74     
    75     for(int i=1;i<=S;i++)
    76         for(int j=1;j<=S;j++)
    77             if(i!=j){
    78                 memset(vis,0,sizeof(vis));
    79                 c=i,d=j;
    80                 if(pd(1,1)) adde(c,d);
    81             }
    82             
    83     for(int i=1;i<=S;i++)
    84         if(!pre[i]) tarjan(i);
    85         
    86     for(int i=1;i<=S;i++)
    87         for(int j=head[i];j;j=nxt[j])
    88             if(scc[i]!=scc[e[j]]) G[scc[i]][scc[e[j]]]=1;
    89     
    90     int ans=0;    
    91     for(int i=1;i<=cnt;i++)
    92         ans=max(ans,dfs(i));
    93         
    94     printf("%d
    ",ans);
    95     return 0;
    96 }
    View Code
  • 相关阅读:
    【C/C++】动态内存分配和链表
    【C/C++】递归算法
    UnicodeMath编码教程
    UnicodeMath数学公式编码_翻译(Unicode Nearly Plain
    浅谈Java反射机制
    lvs--小白博客
    python部署lvs
    python部署galery集群
    python第九章:面向对象--小白博客
    python之yagmail模块--小白博客
  • 原文地址:https://www.cnblogs.com/xkui/p/4551947.html
Copyright © 2011-2022 走看看