zoukankan      html  css  js  c++  java
  • 潘多拉的盒子(bzoj 1194)

    Description

     

    Input

    第一行是一个正整数S,表示宝盒上咒语机的个数,(1≤S≤50)。文件以下分为S块,每一块描述一个咒语机,按照咒语机0,咒语机1„„咒语机S-1的顺序描述。每一块的格式如下。 一块的第一行有两个正整数n,m。分别表示该咒语机中元件的个数、咒语源输出元的个数(1≤m≤n≤50)。 接下来一行有m个数,表示m个咒语源输出元的标号(都在0到n-1之间)。接下来有n行,每一行两个数。第i行(0≤i≤n-1)的两个数表示pi,0和pi,1(当然,都在0到n-1之间)。

    Output

    第一行有一个正整数t,表示最长升级序列的长度。

    Sample Input

    4
    1 1
    0
    0 0
    2 1
    0
    1 1
    0 0
    3 1
    0
    1 1
    2 2
    0 0
    4 1
    0
    1 1
    2 2
    3 3
    0 0

    Sample Output

    3
    /*
          思路比较简单:对于每对i,j,如果满足i能产生的所有字符串j都能产生,则建边,跑最长路。
        但是图可能不是DAG,所以要先预处理缩点,然后再做。
    */
    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #define N 60
    using namespace std;
    int dfn[N],low[N],ins[N],sta[N],val[N],bl[N],indexx,num,top;
    int vis[N][N],head[N],head2[N],dp[N],S,cnt,a,b,flag;
    
    struct Node{int danger[N],lc[N],rc[N];};Node T[N];
    struct node{int to,pre;};node e[N*N*2],e2[N*N*2];
    
    void add(int u,int v){
        e[++cnt].to=v;
        e[cnt].pre=head[u];
        head[u]=cnt;
    }
    void add2(int u,int v){
        e2[++cnt].to=v;
        e2[cnt].pre=head2[u];
        head2[u]=cnt;
    }
    void dfs(int x,int y){
        if(vis[x][y]||flag) return;
        vis[x][y]=1;
        if(T[b].danger[y]&&!T[a].danger[x]){flag=1;return;}
        dfs(T[a].lc[x],T[b].lc[y]);
        dfs(T[a].rc[x],T[b].rc[y]);
    }
    bool check(int i,int j){
        flag=0;a=i;b=j;
        memset(vis,0,sizeof(vis));
        dfs(1,1);
        if(!flag)return true;
        return false;
    }
    void tarjan(int x){
        dfn[x]=low[x]=++indexx;
        sta[++top]=x;
        ins[x]=1;
        for(int i=head[x];i;i=e[i].pre){
            int v=e[i].to;
            if(!dfn[v]){
                tarjan(v);
                low[x]=min(low[x],dfn[v]);
            }
            else if(ins[v])
                low[x]=min(low[x],low[v]);
        }
        int u;
        if(low[x]==dfn[x]){
            ++num;
            do{
                u=sta[top--];
                val[num]++;
                bl[u]=num;
                ins[u]=0;
            }while(u!=x);
        }
    }
    int dfs2(int x){
        if(dp[x])return dp[x];
        int maxn=val[x];
        for(int i=head2[x];i;i=e2[i].pre)
            maxn=max(maxn,dp[e2[i].to]+val[x]);
        dp[x]=maxn;
        return dp[x];
    }
    int main(){
        scanf("%d",&S);
        for(int s=1;s<=S;s++){
            int n,m;
            scanf("%d%d",&n,&m);
            for(int i=1;i<=m;i++){
                int x;scanf("%d",&x);
                T[s].danger[x+1]=1;
            }
            for(int i=1;i<=n;i++){
                int x,y;scanf("%d%d",&x,&y);
                T[s].lc[i]=x+1;T[s].rc[i]=y+1;
            }
        }
        for(int i=1;i<=S;i++)
            for(int j=1;j<=S;j++)
                if(i!=j&&check(i,j))
                    add(i,j);
        for(int i=1;i<=S;i++)if(!dfn[i])tarjan(i);
        for(int i=1;i<=S;i++)
            for(int j=head[i];j;j=e[j].pre)
                if(bl[i]!=bl[e[j].to])add2(bl[i],bl[e[j].to]);
        int ans=0;
        for(int i=1;i<=num;i++)ans=max(ans,dfs2(i));
        printf("%d",ans);
        return 0;
    }
  • 相关阅读:
    Could A New Linux Base For Tablets/Smartphones Succeed In 2017?
    使用libhybris,glibc和bionic共存时的TLS冲突的问题
    6 Open Source Mobile OS Alternatives To Android in 2018
    Using MultiROM
    GPU drivers are written by the GPU IP vendors and they only provide Android drivers
    Jolla Brings Wayland Atop Android GPU Drivers
    How to Use Libhybris and Android GPU Libraries with Mer (Linux) on the Cubieboard
    闲聊Libhybris
    【ARM-Linux开发】wayland和weston的介绍
    Wayland and X.org problem : Why not following the Android Solution ?
  • 原文地址:https://www.cnblogs.com/harden/p/6392002.html
Copyright © 2011-2022 走看看