• 百度之星复赛T6&&hd6149 ——Valley Numer II


    Problem Description

    众所周知,度度熊非常喜欢图。

    它最近发现了图中也是可以出现 valley —— 山谷的,像下面这张图。

    为了形成山谷,首先要将一个图的顶点标记为高点或者低点。标记完成后如果一个顶点三元组<X, Y, Z>中,X和Y之间有边,Y与Z之间也有边,同时X和Z是高点,Y是低点,那么它们就构成一个valley。

    度度熊想知道一个无向图中最多可以构成多少个valley,一个顶点最多只能出现在一个valley中。

    Input

    第一行为T,表示输入数据组数。

    每组数据的第一行包含三个整数N,M,K,分别表示顶点个数,边的个数,标记为高点的顶点个数。

    接着的M行,每行包含两个两个整数Xi,Yi,表示一条无向边。

    最后一行包含K个整数Vi,表示这些点被标记为高点,其他点则都为低点。

    ● 1≤T≤20

    ● 1≤N≤30

    ● 1≤M≤N*(N-1)/2

    ● 0≤K≤min(N,15)

    ● 1≤Xi, Yi≤N, Xi!=Yi

    ● 1≤Vi≤N

    Output

    对每组数据输出最多能构成的valley数目。

    Sample Input
    3
    3 2 2
    1 2
    1 3
    2 3
    3 2 2
    1 2
    1 3
    1 2
    7 6 5
    1 2
    1 3
    1 4
    2 3
    2 6
    2 7
    3 4 5 6 7
    
    Sample Output
    1
    0
    2
    ——————————————————————————————————————————————————————————
    果然状压dp不是很熟悉 比赛的时候没有想出来
    f【i】【j】表示前i块石头 j及高点的情况
    然后枚举两个高点就好辣
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int M=107,maxn=100010;
    int read(){
        int ans=0,f=1,c=getchar();
        while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
        while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
        return ans*f;
    }
    int T,n,m,k,now,ans,cnt;
    int h[M],v[M];
    int f[2][maxn],map[M][M];
    void clear(){
        ans=0; cnt=1;
        memset(map,0,sizeof(map));
        memset(f,0,sizeof(f));
        memset(v,0,sizeof(v));
    }
    int main()
    {
        T=read();
        while(T--){
            int x,y;
            n=read(); m=read(); k=read();
            clear();
            for(int i=1;i<=m;i++) x=read(),y=read(),map[x][y]=map[y][x]=1;
            for(int i=1;i<=k;i++) h[i]=read(),v[h[i]]=1;
            int s=(1<<k)-1;
            for(int i=1;i<=n;i++)if(!v[i]){
                now=(++cnt)&1;
                memset(f[now],0,sizeof(f[now]));
                for(int j=0;j<=s;j++) f[now][j]=f[now^1][j];
                for(int j=0;j<=s;j++){ 
                    for(int k1=1;k1<=k;k1++) if(!(j&(1<<(k1-1)))&&map[i][h[k1]]){
                        for(int k2=k1+1;k2<=k;k2++) if(!(j&(1<<(k2-1)))&&map[i][h[k2]]){
                            int nows=j^(1<<(k1-1))^(1<<(k2-1));
                            f[now][nows]=max(f[now][nows],f[now^1][j]+1);
                        }
                    } 
                }
            }
            for(int i=0;i<=s;i++) ans=max(ans,f[now][i]);
            printf("%d
    ",ans);
        }
        return 0;
    }
    View Code

  • 相关阅读:
    RabbitMQ消息队列———安装(一)
    Tornado之自定义异步非阻塞的服务器和客户端
    爬虫之解析微信的网页版(分析后台,不分析前端)
    阻塞I/O、非阻塞I/O和I/O多路复用
    Git之安装管理
    MongoDB下载以及安装
    Python3学习笔记(十六):随机数模块random
    Python3学习笔记(十五):常用时间模块time和datetime
    Python3学习笔记(十四):可迭代对象、迭代器和生成器
    unittest详解(七) 自动生成测试报告
  • 原文地址:https://www.cnblogs.com/lyzuikeai/p/7392166.html
Copyright © 2020-2023  润新知