hdu 6149 Valley Numer II(状压+ 枚举)

来源:互联网 发布:淘宝网店客服工作职责 编辑:程序博客网 时间:2024/06/05 12:13

Valley Numer II

Time Limit: 12000/6000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 310    Accepted Submission(s): 101


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
33 2 21 21 32 33 2 21 21 31 27 6 51 21 31 42 32 62 73 4 5 6 7
 

Sample Output
102


n只有30,k只有15,直接暴力所有情况,枚举每一个低位点,暴力考虑与他相连的高位点


#include <iostream>#include <cstdio>#include <bits/stdc++.h>using namespace std;typedef long long LL;const int N = 1e4+10;const LL mod = 1e9+7;int h[N], a[N], w[100][100];int dp[2][(1<<15)+10];int main(){    int t;    scanf("%d", &t);    while(t--)    {        int n, m, kx;        scanf("%d %d %d", &n, &m, &kx);        memset(h,0,sizeof(h));        memset(w,0,sizeof(w));        for(int i=0; i<m; i++)        {            int x, y;            scanf("%d %d", &x, &y);            w[x][y]=w[y][x]=1;        }        for(int i=0; i<kx; i++)        {            scanf("%d", &a[i]);            h[a[i]]=1;        }        memset(dp,0,sizeof(dp));        int now=0;        for(int i=1; i<=n; i++)        {            if(h[i]) continue;            now^=1;            for(int j=0;j<(1<<kx);j++) dp[now][j]=dp[now^1][j];            for(int j=0; j<(1<<kx); j++)            {                for(int k=0; k<kx; k++)                {                    if(!(j&(1<<k))&&(w[i][a[k]]))                    {                        for(int k1=k+1;k1<kx;k1++)                        {                            if(!(j&(1<<k1))&&(w[i][a[k1]]))                            {                                int state=(j)|(1<<k)|(1<<k1);                                dp[now][state]=max(dp[now][state],dp[now^1][j]+1);                            }                        }                    }                }            }        }        int ans=0;        for(int i=0;i<(1<<kx);i++) ans=max(ans,dp[now][i]);        printf("%d\n",ans);    }    return 0;}








原创粉丝点击