zoukankan      html  css  js  c++  java
  • PETS

    问题:
    xxxxxyt学姐经常一个人在家,难免会感到寂寞,于是学姐养了n只可爱的宠物,比如皮皮虾、大蟒蛇、藏狐、安康鱼…但即便如此学姐还是感到无聊。突然有一天,学姐想到了让宠物们互相对战的消遣方法(请不要给动物保护协会打电话!)。学姐让宠物们两两进行对战,n*(n-1)/2场对战后,学姐得到了一张相生相克图,然后又根据自己的喜好,把宠物们分成了一队与二队。就在队伍分好后,学姐的强迫症又犯了,她希望自己的两支队伍都满足这样一个性质:存在某种排列,使得排在后面的宠物能够击败排在前面的所有宠物。但学姐的懒惰大家都是知道的,所以她找到了你,希望你能告诉她这两支队伍是否均满足要求,如果是,她还希望你告诉她最多可以从二队中抽出多少只宠物放在一队,使得两支队伍仍然满足要求。努力解决问题吧,而xxxxxyt学姐,瘫躺。
    输入格式
    第一行输入两个数字n和m,分别表示学姐有n只宠物,其中被分到一队的宠物有m只。
    接下来n行每行n个数字,ai,j表示第i只宠物是否能战胜第j只宠物,保证ai,i=0且ai,j==!aj,i。
    接下来一行m个数字,表示有哪些宠物被分到了一队。
    输出格式
    如果两支队伍均不能让xxxxxyt满意,则输出“NO”;否则输出“YES”,并输出一个最大的k,使得从二队中非任意地抽出k只宠物放入一队后,两支队伍仍然满足条件。详细格式见样例输出。
    解:
    此题不能用tarjan贪心 可能出现环套环的情况
    注意到这是一个有向完全图 所以top序列在不存在环的情况下一定是唯一的
    并且题目还让你判断了环 这不明摆着让你利用top排序进行DP吗? 这种在top序列上进行Dp的方式其实很常见
    考虑建立多层图
    我们对唯一存在的topp 求两个topp序列 问题可以转化为
    给你两个数列 AB 问题B最多能够插入A中多少并且B序列的顺序是不变的
    预处理出B数列中的每一个数所能插入的位置
    定义 f[i][j] 表示前i个A前i个B 所能选的最大的个数
    状态转移方程就很好写具体看代码
    code:

        #include<stdio.h>
    #include<iostream>
    #include<cstdio>
    #include<queue>
    using namespace std;
    #define maxnn 2000
    #define mm 1000010
    int mapp[maxnn][maxnn];
    int las[mm],en[mm],nex[mm],tot;
    int rr1[mm],rr2[mm];
    
    void add(int a,int b)
    {
        en[++tot]=b;
        nex[tot]=las[a];
        las[a]=tot;
    }
    int las1[mm],en1[mm],nex1[mm],tot1;
    void add1(int a,int b)
    {
        en1[++tot1]=b;
        nex1[tot1]=las1[a];
        las1[a]=tot1;
    }
    
    int n,m;
    int ru[maxnn];
    int is[maxnn];
    int rk1[maxnn],rk2[maxnn],cnt1,cnt2;
    int maxx[maxnn],minn[maxnn];
    void toppsort()
    {
        queue<int> Q;
        int num=0;
        for(int i=1;i<=n;i++)
        {
            if(is[i]&&(!ru[i]))
            {
                rk1[++cnt1]=i;
                rr1[i]=cnt1;
                Q.push(i);
                num++;
            }
        }
        while(Q.size())
        {
            int r=Q.front();Q.pop();
            for(int i=las[r];i;i=nex[i])
            {
                int u=en[i];
                if(!is[u]) continue;
                ru[u]--;
                if((!ru[u])&&(is[u]))
                {
                    num++;
                    rk1[++cnt1]=u;rr1[u]=cnt1;
                    Q.push(u);
                }
            }
        }
        if(num<m) {puts("NO"); exit(0);}
        num=0;
        for(int i=1;i<=n;i++)
        {
            if((!is[i])&&(!ru[i]))
            {
                Q.push(i);
                rk2[++cnt2]=i;
                rr2[i]=cnt2;
                num++;
            }
        }
        while(Q.size())
        {
            int r=Q.front(); Q.pop();
            for(int i=las[r];i;i=nex[i])
            {
                int u=en[i];
                if(is[u]) continue;
                ru[u]--;
                if((!ru[u])&&(!is[u]))
                {
                    rk2[++cnt2]=u;
                    rr2[u]=cnt2;
                    Q.push(u);
                    num++;
                }
            }
        }
        if(num<n-m)
        {
            puts("NO"); exit(0);
        }
    }
    int f[maxnn][maxnn];
    int main()
    {
    
        cin>>n>>m;
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=n;j++)
            {
                scanf("%d",&mapp[i][j]);
                if(mapp[i][j]==1)
                {
                    add(j,i);
                    add1(i,j);
                }
            }
        }
        int x;
        for(int i=1;i<=m;i++)
        {
            scanf("%d",&x);
            is[x]=1;
        }
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
            {
                if(mapp[i][j]&&is[i]&&is[j])ru[i]++;
                if(mapp[i][j]&&(!is[i])&&(!is[j])) ru[i]++;
            }
        toppsort();
        for(int i=1;i<=n;i++)
        {
            minn[i]=100000;
        }
        for(int i=1;i<=n;i++)
        {
            if(is[i])
                for(int j=las1[i];j;j=nex1[j])
                {
                    int u=en1[j];
                    if(!is[u])
                    {
                        if(minn[u]==0) minn[rr2[u]]=rr1[i];
                        else minn[rr2[u]]=min(minn[rr2[u]],rr1[i]);
                    }
                }
            else
            {
                for(int j=las1[i];j;j=nex1[j])
                {
                    int u=en1[j];
                    if(is[u])
                    maxx[rr2[i]]=max(maxx[rr2[i]],rr1[u]);
                }
                
    
            }
        }
        int ans=0;
        for(int i=0;i<=cnt1+1;i++)
        for(int j=0;j<=cnt2;j++)
        {
          
           if(i>=1) f[i][j]=max(f[i-1][j],f[i][j]);
            if(j>=1) f[i][j]=max(f[i][j-1],f[i][j]);
            if((i>maxx[j])&&(i<=minn[j]))
            {
           
                if(j>=1)f[i][j]=max(f[i][j],f[i][j-1]+1);
            }
            ans=max(ans,f[i][j]);
        }
        printf("YES ");
        cout<<ans;
    }
    
  • 相关阅读:
    课程的添加与发布
    openlayers 框选得到在选框内的要素,并标注出这些要素的名称
    手写js前端分页功能实现
    eclipse安装html编辑器插件
    Redis持久化技术
    java获取指定时间
    java生成Cron表达式
    CentOS7 ifcfg-ens33(没有eth0网卡) 网卡配置 静态IP地址
    java代码关闭tomcat程序
    Tomcat控制台乱码问题
  • 原文地址:https://www.cnblogs.com/OIEREDSION/p/11827997.html
Copyright © 2011-2022 走看看