#include <iostream>
#include <string>
#include <complex>
#include <vector>
#include <stack>
#include <cstdio>
#include<functional>
#include<cmath>
#include<ctime>
#include<cstring>
#include<algorithm>
using namespace std;
typedef complex<double> cp;
#define ll long long
#define re register
#define sci(x) scanf("%d",&x)
#define scl(x) scanf("%lld",&x)
#define scf(x) scanf("%lf",&x)
#define print(arr,n) for(int i=0;i<n;i++){for(int j=0;j<n;j++)printf("%d ",arr[i][j]);printf("\n");}
#define fo(a,b,c)for(int a=b;a<=c;a++)
#define getname(x) #x
const int maxn=1e4+5;
int adj[maxn],nex[maxn<<1],to[maxn<<1];
int bag[101][2][101];
int rel[101][101],n,x,vis[101],ops[101],tot,sz[101][2];
int dp[101][101],rec[101][101],ans1[101],ans2[101];
void add(int i,int j)
{
nex[0]++;
nex[nex[0]]=adj[i];
adj[i]=nex[0];
to[nex[0]]=j;
}
void adds(int i,int j)
{
add(i,j);
add(j,i);
}
bool bfs(int i)
{
stack<int>st;
st.push(i);
ops[i]=1;
bag[++sz[tot][1]][ops[i]][tot]=i;
vis[i]=1;
while(!st.empty()){
int tp=st.top();
st.pop();
for(int k=adj[tp];k;k=nex[k]){
int t=to[k];
if(vis[t]){
if(ops[t]==ops[tp])return false;
}
else {
st.push(t);
ops[t]=!ops[tp];
bag[++sz[tot][ops[t]]][ops[t]][tot]=t;
vis[t]=1;
}
}
}
tot++;
return true;
}
bool solve()
{
for(int i=0;i<n;i++){
if(!vis[i]&&!bfs(i)){
return true;
}
}
for(int i=0;i<=tot;i++)
for(int j=0;j<=n;j++)dp[i][j]=-1;dp[0][0]=0;
for(int i=1;i<=tot;i++){
int o=sz[i-1][0];
int l=sz[i-1][1];
for(int j=0;j<=n;j++){
if(j>=o&&~dp[i-1][j-o]){
dp[i][j]=true;
rec[i][j]=0;
}
if(j>=l&&~dp[i-1][j-l]){
dp[i][j]=true;
rec[i][j]=1;
}
}
}
int fin=0;
for(int i=n/2;i;i--){
if(dp[tot][i]!=-1){
fin=i;break;
}
}
for(int j=tot;j;j--){
int ch=rec[j][fin];
int bs=sz[j-1][ch];
for(int k=1;k<=bs;k++){
ans1[++ans1[0]]=bag[k][ch][j-1];
}fin-=sz[j-1][ch];
ch=!ch;
bs=sz[j-1][ch];
for(int k=1;k<=bs;k++)
{
ans2[++ans2[0]]=bag[k][ch][j-1];
}
}
sort(ans1+1,ans1+1+ans1[0]);
sort(ans2+1,ans2+1+ans2[0]);
return false;
}
void setR()
{
sci(n);
for(int i=0;i<n;i++){
while(sci(x)&&x){rel[i][x-1]=1;}
}
for(int i=0;i<n;i++)
for(int j=i+1;j<n;j++){
if(!(rel[i][j]&&rel[j][i]))
adds(i,j);
}
}
int main()
{
setR();
if(solve()){
printf("No solution");
}
else {
printf("%d ",ans1[0]);
for(int i=1;i<=ans1[0];i++){
printf("%d ",ans1[i]+1);
}
printf("\n");
printf("%d ",ans2[0]);
for(int i=1;i<=ans2[0];i++){
printf("%d ",ans2[i]+1);
}
printf("\n");
}
}
P1285 队员分组(二分图+背包)
最新推荐文章于 2023-07-22 21:19:35 发布