Team them up!

题意:

给出n个人以及认识其他人的情况,现在要把所有人分成两队,每队至少一人,求使两队人数差距最小且每队内部的人都相互认识的分队情况。

分析:

这道题让我学习到了不少,首先看到使差距最小就想到了背包,但是不会表示分队情况。看了别人的思路,这个很明显是要判断是否是二分图,让不是相互认识的两人连一条边,若不是二分图则不能分成两队。利用染色法判断二分图,则每个连通分量都包含0,1两个集合。

dp[i][j]表示i个联通分量能组成符合条件的人数为j的一队,par[i][j]记录路径

#include <map>
#include <set>
#include <list>
#include <cmath>
#include <queue>
#include <stack>
#include <cstdio>
#include <vector>
#include <string>
#include <cctype>
#include <complex>
#include <cassert>
#include <utility>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
using namespace std;
typedef pair<int,int> PII;
typedef long long ll;
#define lson l,m,rt<<1
#define pi acos(-1.0)
#define rson m+1,r,rt<<11
#define All 1,N,1
#define N 110
#define read freopen("in.txt", "r", stdin)
const ll  INFll = 0x3f3f3f3f3f3f3f3fLL;
const int INF= 0x7ffffff;
const int mod =  1000000007;
int n,tim,num;
int dp[N][N],par[N][N],mapc[N][N],part[N][2];
int color[N],dfn[N],f[N],road[N][N][2];
vector<int>e[N];
int dfs(int u){
    dfn[u]=++tim;
    road[num][++part[num][color[u]]][color[u]]=u;
    for(int i=0;i<e[u].size();++i){
            int v=e[u][i];
        if(dfn[v]==0){
            color[v]=(!color[u]);
            if(dfs(v)==0)return 0;
        }
        else{
            if(v!=u&&color[u]==color[v])return 0;
        }
    }
    return 1;
}
void hand(){
    int v;
    for(v=n/2;v>=0;--v){
        if(dp[num][v])
            break;
    }
    if(v==0){printf("No solution\n");return;}
    memset(f,0,sizeof(f));
    int tmp=v,t;
    for(int i=num;i>=0;--i){
        t=par[i][tmp];
        tmp-=part[i][t];
        for(int j=1;j<=part[i][t];++j)
            f[road[i][j][t]]=1;
    }
    printf("%d",v);
    for(int i=1;i<=n;++i)
        if(f[i])
        printf(" %d",i);
    printf("\n");
    printf("%d",n-v);
    for(int i=1;i<=n;++i)
        if(!f[i])
        printf(" %d",i);
    printf("\n");
}
void solve(){
    memset(part,0,sizeof(part));
    memset(color,0,sizeof(color));
    memset(dfn,0,sizeof(dfn));
    memset(dp,0,sizeof(dp));
    tim=num=0;
    int k;
    for(k=1;k<=n;++k){
        if(!dfn[k]){
            ++num;
            if(dfs(k)==0)break;
        }
    }
    if(k<=n)printf("No solution\n");
    else{
        dp[0][0]=1;
        for(int i=1;i<=num;++i)
        for(int j=0;j<=n/2;++j){
            int tmp=j-part[i][0];
            if(tmp>=0&&dp[i-1][tmp]){
                dp[i][j]=1;
                par[i][j]=0;
            }
            tmp=j-part[i][1];
            if(tmp>=0&&dp[i-1][tmp])
            {
                dp[i][j]=1;
                par[i][j]=1;
            }
        }
        hand();
    }
}
int main()
{
    int ca=0;
    scanf("%d",&ca);
    while(ca--){
        scanf("%d",&n);
        int a;
        memset(mapc,0,sizeof(mapc));
        for(int i=1;i<=n;++i)
            e[i].clear();
        for(int i=1;i<=n;++i){
            while(~scanf("%d",&a)&&a){
                mapc[i][a]=1;
            }
        }
        for(int i=1;i<=n;++i)
            for(int j=i+1;j<=n;++j)
        if(mapc[i][j]==0||mapc[j][i]==0){
            e[i].push_back(j);
            e[j].push_back(i);
        }
        solve();
        if(ca)printf("\n");
    }
return 0;
}
时间: 2024-11-05 12:14:00

Team them up!的相关文章

UVa 1627 - Team them up!——[0-1背包]

Your task is to divide a number of persons into two teams, in such a way, that: everyone belongs to one of the teams; every team has at least one member; every person in the team knows every other person in his team; teams are as close in their sizes

HDU 3296 &amp; POJ 3138 Acm Team Section(数学)

题目链接: HDU: http://acm.hdu.edu.cn/showproblem.php?pid=3296 POJ:  http://poj.org/problem?id=3138 Acm Team Section Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 159    Accepted Submission(s): 47

Team Queue

Team Queue Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 129 Accepted Submission(s): 63   Problem Description Queues and Priority Queues are data structures which are known to most computer scie

team viewer - rollback framework could not be initialized

rollback framework could not be initialized, 在安装team viewer 的时候出现的这个错误信息,求大师帮忙 https://zhidao.baidu.com/question/521794345.html

Sample Apps by Android Team -- Amazed

Sample Apps by Android Team 代码下载:http://pan.baidu.com/s/1eSNmdUE 本次是项目Amazed代码学习记录. 一.创建自定义View @.在onSizeChanged中,通过如参w(宽)和h(高)的比较来判断手机是处于横向(Landscape)还是纵向(Portrait). @.在onDraw中进行自定义View的界面绘制. @.绘制界面需要Canvas和Paint: 1.Cnavas:用来控制画什么,比如画直线(drawLine).画矩

Uva 540.Team Queue

队列问题,思路较为清晰 通过模拟操作可以发现可以先队内排列,然后进行队伍排列 其中个别操作由于vector.map嵌套,可能会发生打错凌乱的情况. 1 #include <cstdio> 2 #include <vector> 3 #include <queue> 4 #include <map> 5 #include <algorithm> 6 7 using namespace std; 8 9 int kase=0; 10 11 class

team talk 主要框架

Android TeamTalk的原型是Android-IM, 注:本文假设你已经有Android开发环境,且对Android开发的基本常识有所了解 本文以eclipse为例启动Eclipse,导入Android客户端项目,请确保你当前的Android SDK是最新版. 如果编译出错,请修改项目根目录下的 project.properties 文件. 一.程序所依赖项目信息 1.mgimlibs git地址:http://gitlab.mogujie.org/androidop-team/mgi

Gun N&#39; Rose Team Review

一看到这个项目就被他的功能给吸引了.回忆起以前看到一个东西很新奇想去网上查询它是什么,但是又不知道应该怎样去描述它,于是在搜索引擎的输入框中键入.删除.键入.删除的可笑经历的时候,我就越发感觉到这个app的必要性了.画出查询对象的大致轮廓,系统自动搜筛选出相似的图片,这个app实现了“所见即所得”,令人称赞. 当然,这个app也存在很多局限性,比如说它返回的图片数量很大,没能实现精确定位,如果能让用户在输入时添加对对象的模糊描述,比如说:不是房子,像苹果等无疑将提高搜索的准确度.另外,这个app

@Team协作:新媒体初创公司的业绩屡创新高的秘密

共同协作这个词汇相信很多创业者都曾不止一次见过或者听说过,这个词汇的热门来自当下面对提高效率以及团队协同性拓展的需求,而作为从个人站长转型至创业者,当面对团队以及客户的时候,初创公司的效率决定了这家公司的寿命. 作 为一家新媒体初创公司,从一开始就选择了创业工具组合来完成产品的设计到团队的管理,再到业务的销售与客户关系维护,从产品原型设计Axure到邮件客户 端Foxmail,从金数据到IMO云办公室,我们的目的就是为了提高效率让团队更专注产品服务,但是零散的工具并没有起到太多的作用. 目前微信

RHEL7 -- 使用team替换bonding实现链路聚合网卡绑定

将网卡enp0s8.enp0s9进行链路绑定 安装teamd包 # yum install teamd 创建一个team链接 # nmcli con add con-name team0 type team ifname team0 config '{"runner":{“name”:"activebackup"}}' Connection 'team0' (7100f55b-3fa5-46d3-84e8-26803f2a6117) successfully add