Solution team grouping
Subject to the effect: each has some understanding of, \ (A \) recognize \ (B \) does not necessarily have \ (B \) recognize \ (A \) , you put all the people were divided into two teams, the same requirements people within the team must be mutually recognized, on this premise makes the number two teams as close as possible, seeking grouping scheme
Bipartite graph, backpacks
Analysis: must be mutually recognized that hard to deal with, people we can not know even the top, so that it becomes a no edge between people within the same team
In this case, we found that different people communication components can be calculated independently of each other, respectively
For points within the connected component, we take it dyed black and white, and there is no edge between the point of the same color, which is the definition of a bipartite graph, we once \ (BFS \) can be done, and if the connected component without any solution the whole problem has no solution
So that both the number of teams and then close, we find a connected component of black spots can either case, we ran a Boolean backpack, from \ (n / 2 \) enumeration seek what can not spell \ (x \ ) a black spot on it
Double experience problems of cancer
#include <cstdio>
#include <cctype>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;
const int maxn = 128;
inline int read(){
int x = 0;char c = getchar();
while(!isdigit(c))c = getchar();
while(isdigit(c))x = x * 10 + c - '0',c = getchar();
return x;
}
vector<int> G[maxn],vec[maxn][2],ans[2];
inline void addedge(int from,int to){G[from].push_back(to);}
int n,tmp[maxn][maxn],f[maxn][maxn],opt[maxn][maxn],vis[maxn],col[maxn],vec_tot;
inline bool bfs(int s){
queue<int> Q;Q.push(s);vis[s] = 1;
vec_tot++;
while(!Q.empty()){
int u = Q.front();Q.pop();
vec[vec_tot][col[u]].push_back(u);
for(int v : G[u])
if(!vis[v])col[v] = col[u] ^ 1,vis[v] = 1,Q.push(v);
else if(col[v] == col[u])return false;
}
return true;
}
inline void solve(){
n = read();
for(int u = 1,v;u <= n;u++)
while((v = read()))tmp[u][v] = 1;
for(int u = 1;u <= n;u++)
for(int v = u + 1;v <= n;v++)
if(!(tmp[u][v] && tmp[v][u]))addedge(u,v),addedge(v,u);
for(int i = 1;i <= n;i++)
if(!vis[i] && !bfs(i)){
puts("No solution");
return;
}
f[0][0] = 1;
for(int i = 1;i <= vec_tot;i++)
for(int j = 0;j <= n;j++){
if(j >= vec[i][0].size() && f[i - 1][j - vec[i][0].size()])f[i][j] = 1,opt[i][j] = 0;
if(j >= vec[i][1].size() && f[i - 1][j - vec[i][1].size()])f[i][j] = 1,opt[i][j] = 1;
}
int now;
for(int i = n >> 1;i >= 0;i--)
if(f[vec_tot][i]){now = i;break;}
for(int i = vec_tot;i >= 1;i--){
for(auto x : vec[i][opt[i][now]])ans[0].push_back(x);
for(auto x : vec[i][opt[i][now] ^ 1])ans[1].push_back(x);
now -= vec[i][opt[i][now]].size();
}
sort(ans[0].begin(),ans[0].end());
sort(ans[1].begin(),ans[1].end());
printf("%d ",(int)ans[0].size());
for(auto x : ans[0])printf("%d ",x);
putchar('\n');
printf("%d ",(int)ans[1].size());
for(auto x : ans[1])printf("%d ",x);
putchar('\n');
}
int main(){
solve();
}