本题相当暴力……对于自己的牌全排列,然后对对手的牌全排列。如果对手所有的排列都不能赢,则这该排列合法,更新一下答案就可以了。
#define M 10005
typedef map<LL, LL> Hash;
map<string,int> name;
string st[52];
set<int> op[M];
int d[25],p[25];
string ans="";
int n,T;
bool lost()
{
int i,j,me=1,you=1;
while (me<=n && you<=n)
{
if (op[p[you]].count(d[me]))
me++;
else
you++;
}
if (me>n) return true;
return false;
}
void checkans()
{
string tmp="";
int i;
for (i=1;i<n;i++)
{
tmp+=st[d[i]];
tmp+=' ';
}
tmp+=st[d[n]];
if (ans=="#")
{
ans=tmp;
}
else if (ans>tmp)
{
ans=tmp;
}
}
int main()
{
int i,j;
scanf("%d",&T);
for (int ca=1;ca<=T;ca++)
{
ans="#";
scanf("%d",&n);
name.clear();
int cnt=1;
for (i=1;i<=n;i++)
{
cin>>st[i];
name[st[i]]=i;
}
for (i=1;i<n+1;i++) op[i].clear();
for (i=1;i<=n;i++)
{
int t;
scanf("%d",&t);
for (j=0;j<t;j++)
{
string tmp;
cin>>tmp;
op[i].insert(name[tmp]);
}
}
bool Find=0;
for (i=1;i<=n;i++) d[i]=i;
do
{
bool ck=1;
for (i=1;i<=n;i++)
p[i]=i;
do
{
if (lost())
{
ck=0;
break;
}
}while (next_permutation(p+1,p+n+1));
if (ck)
{
Find=1;
checkans();
}
}while (next_permutation(d+1,d+n+1));
printf("Case %d: ",ca);
if (Find)
{
puts("Yes");
cout<<ans<<endl;
}
else puts("No");
}
return 0;
}