Solution to a problem P1285 [group members]

Topic Link

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();
}

Guess you like

Origin www.cnblogs.com/colazcy/p/11792411.html