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;
    }
  • 相关阅读:
    php 内置的 webserver 研究。
    php 系列
    git 以及 github 使用系列
    中午和同事聊天,了解的一点网络方面的东西。
    javascript中0.01*2324=23.240000000000002 ?
    javascript的 replace() 方法的使用讲解
    PHP中的ORM
    javascript 函数 add(1)(2)(3)(4)实现无限极累加 —— 一步一步原理解析
    animate.css
    面向对象编程
  • 原文地址:https://www.cnblogs.com/harden/p/6392002.html
Copyright © 2011-2022 走看看