先把在同一网络中的电脑整理出来,然后再枚举子集,最后就是一般的状压dp。
#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn=16;
int p[1<<maxn],dp[1<<maxn],cover[1<<maxn];
int main()
{
int n,kase=0;
while(scanf("%d",&n)&&n)
{
for(int i=0;i<n;i++)
{
int m;
p[i]=(1<<i);
scanf("%d",&m);
int x;
while(m--) {scanf("%d",&x);p[i]|=(1<<x);}
}
for(int s=0;s<(1<<n);s++)
{
cover[s]=0;
for(int j=0;j<n;j++)
if(s&(1<<j)) cover[s]|=p[j];
}
int ALL=(1<<n)-1;
dp[0]=0;
for(int s=0;s<(1<<n);s++)
{
dp[s]=0;
for(int s0=s;s0;s0=(s0-1)&s)
{
if(cover[s0]==ALL) dp[s]=max(dp[s],dp[s^s0]+1);
}
}
printf("Case %d: %d\n",++kase,dp[ALL]);
}
return 0;
}