#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
int f[110][110];
int sum[110][3];
int dp[105][105][105];
int de[105][105][105];
int col[110][3];
int ans0[120],ans1[120];
int n;
bool flag[120];
void input()
{
memset(f,0,sizeof(f));
memset(sum,0,sizeof(sum));
memset(dp,0,sizeof(dp));
memset(de,0,sizeof(de));
memset(col,0,sizeof(col));
int x;
scanf("%d",&n);
for (int i=1;i<=n;i++)
while (scanf("%d",&x)&&x!=0)
f[i][x]=1;
for (int i=1;i<=n;i++)
for (int j=i+1;j<=n;j++)
{
if (i==j) continue;
if (f[i][j]==1&&f[j][i]==1) {f[i][j]=0,f[j][i]=0;}
else {f[i][j]=1,f[j][i]=1;}
}
}
bool dfs(int x,int y,int d)
{
//cout<<x<<endl;
flag[x]=true;
col[x][1]=d;
col[x][0]=y;
sum[y][d]++;
/*for (int i=1;i<=n;i++)
printf("%d %d %d\n",i,col[i][0],col[i][1]);*/
for (int i=1;i<=n;i++)
{
if (f[x][i]==0||i==x) continue;
if (flag[i]&&col[i][1]==d) return false;
if (!flag[i])
{
if (dfs(i,y,d^1)==false)
return false;
}
}
return true;
}
void work_part()
{
memset(flag,0,sizeof(flag));
for (int i=1;i<=n;i++)
if (!flag[i])
{
if (!dfs(i,i,0))
{
printf("No solution\n");
exit(0);
}
}
}
void work_dp()
{
memset(dp,0,sizeof(dp));
dp[0][0][0]=1;
for (int i=1;i<=n;i++)
{
for (int j=0;j<=n;j++)
for (int k=0;k<=n;k++)
if (dp[i-1][j][k])
{
dp[i][j+sum[i][0]][k+sum[i][1]]=1;
de[i][j+sum[i][0]][k+sum[i][1]]=0;
dp[i][j+sum[i][1]][k+sum[i][0]]=1;
de[i][j+sum[i][1]][k+sum[i][0]]=1;
}
}
}
void out_dfs(int x,int y1,int y2)
{
if (x==0) return;
if (sum[x][0]==sum[x][1]&&sum[x][0]==0)
{
out_dfs(x-1,y1,y2);
return ;
}
if (de[x][y1][y2]==0)
{
for (int i=1;i<=n;i++)
{
if (col[i][0]==x&&col[i][1]==0)
ans0[++ans0[0]]=i;
if (col[i][0]==x&&col[i][1]==1)
ans1[++ans1[0]]=i;
}
out_dfs(x-1,y1-sum[x][0],y2-sum[x][1]);
}
else
{
for (int i=1;i<=n;i++)
{
if (col[i][0]==x&&col[i][1]==1)
ans0[++ans0[0]]=i;
if (col[i][0]==x&&col[i][1]==0)
ans1[++ans1[0]]=i;
}
out_dfs(x-1,y1-sum[x][1],y2-sum[x][0]);
}
}
void output()
{
int minf,k1,k2;
for (int i=0;i<=n;i++)
for (int j=0;j<=n;j++)
if (dp[n][i][j]==1&&abs(i-j)<minf)
{
minf=abs(i-j);
k1=i;
k2=j;
}
out_dfs(n,k1,k2);
printf("%d",ans0[0]);
for (int i=1;i<=ans0[0];i++) printf(" %d",ans0[i]);
printf("\n");
printf("%d",ans1[0]);
for (int i=1;i<=ans1[0];i++) printf(" %d",ans1[i]);
printf("\n");
}
int main()
{
// freopen("test.txt","r",stdin);
input();
work_part();
work_dp();
output();
return 0;
}
先二分图染色,划出不同的块
然后f[k][i][j]表示分到第k个块第一组有i个人,第二组有j个人就好
然后g++报wa,交c++能ac简直神奇.