Team them up!

Input file teams.in
Output file teams.out

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 as possible.

This task may have many solutions. You are to find and output any solution,
or to report that solution does not exist.

Input

For simplicity, all persons are assigned a unique integer identifier
from 1 to N.

The first line in the input file contains a single integer number N
(2 ≤ N ≤ 100) - the total number of persons to divide into teams, followed
by N lines - one line per person in ascending order of their identifiers.
Each line contains the list of distinct numbers Aij
(1 ≤ Aij ≤ N, Aij ≠ i), separated by spaces.
The list represents identifiers of persons that ith person knows.
The list is terminated by 0.

Output

If the solution to the problem does not exist, then write a single
message "No solution" (without quotes) to the output file.
Otherwise write a solution on two lines. On the first line of
the output file write the number of persons in the first team,
followed by the identifiers of persons in the first team,
placing one space before each identifier. On the second line
describe the second team in the same way. You may write teams
and identifiers of persons in the team in any order.

Sample input #1

5
3 4 5 0
1 3 5 0
2 1 4 5 0
2 3 5 0
1 2 3 4 0

Output for the sample input #1

No solution

Sample input #2

5
2 3 5 0
1 4 5 3 0
1 2 5 0
1 2 3 0
4 3 2 1 0

Sample output for the sample input #2

3 1 3 5
2 2 4

简单地说,就是,一个N个节点的有向图,将节点分成两个集合,满足以下四个条件:
1. 每个节点属于其中一个集合
2. 每个集合至少有一个节点
3. 集合里的每一个节点都有边连向同一个集合里的其他点
4. 被分成的两个集合的大小要尽量接近

如果不能满足上述条件,输出 No solution ,否则输出这两个集合

题解

参照ylfdrib的题解。

首先,求原图的补图,同时把有向图转化为无向图,即:对于节点u, v,如果没有边<u, v>或<v, u>,则建无向边(u, v)

分析一下现在这个图,如果u, v相连,表明u, v不能在同一个集合里,对于这个问题我们就有了感觉,先求图的连通分量,对于同一个连通分量,我们用二分图着色法,把整个连通分量里的点分到两个集合里,当然,如果着色失败,则无解,输出 No solution ,否则,这m个连通分量就构成了m个集合对(xi, yi),xi表示第i个连通分量中着色为0的集合,yi表示第i个连通分量中着色为1的集合,这样问题就转化成:对这m个集合对,每对里选出一个集合,构成A集合,剩余的构成B集合,要求A,B大小尽量接近,这样我们就可以用动态规划来搞定了。

DP方程:dp[i][j] = (dp[i][j - cnt[i][0]] | dp[i][j - cnt[i][1]] ) (1 <= i <= scc, 0 <= j <= N / 2)

dp[i][j] = 1 表示前i个连通分支,可以构成符合要求的节点数为j的集合

这里暂且用scc表示连通分支个数,N表示总节点个数,cnt[i][0]表示第i个分支中被着色成0的节点个数,cnt[i][1]表示第i个分支中被着色成1的节点个数,同时记录dp路径,这样这道题就算彻底搞定了

#include<iostream>
#include<cstring>
#include<vector>
#define rg register
#define il inline
#define co const
template<class T>il T read(){
rg T data=0,w=1;rg char ch=getchar();
for(;!isdigit(ch);ch=getchar())if(ch=='-') w=-w;
for(;isdigit(ch);ch=getchar()) data=data*10+ch-'0';
return data*w;
}
template<class T>il T read(rg T&x) {return x=read<T>();}
typedef long long ll;
using namespace std; co int N=201;
int n,a[N],c[N],num[2],cnt,f[N][N],g[N][N];
pair<int,int> p[N];
#define x first
#define y second
vector<int> e[N],d[N][2],ans[2]; bool dfs(int x,int color){
c[x]=color,++num[color],d[cnt][color].push_back(x);
for(unsigned i=0;i<e[x].size();++i){
int y=e[x][i];
if(c[y]==-1){
if(!dfs(y,color^1)) return 0;
}
else if(c[y]==color) return 0;
}
return 1;
}
void print(int k,int x){
if(!k) return;
int t=g[k][x];
for(int i=0;i<2;++i)
for(unsigned j=0;j<d[k][i].size();++j)
ans[i^t].push_back(d[k][i][j]);
print(k-1,x+d[k][t].size()-d[k][t^1].size());
}
int main(){
read(n);
memset(c,-1,sizeof c);
for(int i=1;i<=n;++i){
memset(a,0,sizeof a);
for(int x;read(x);) a[x]=1;
for(int j=1;j<=n;++j)if(j!=i&&!a[j])
e[i].push_back(j),e[j].push_back(i);
}
for(int i=1;i<=n;++i)if(c[i]==-1){
num[0]=num[1]=0,++cnt;
if(!dfs(i,0)) return puts("No solution"),0;
p[cnt]=make_pair(num[0],num[1]);
}
f[0][100]=1;
for(int i=1;i<=cnt;++i)
for(int j=0;j<=200;++j)if(f[i-1][j]){
int x=p[i].x,y=p[i].y;
f[i][j+x-y]=1,g[i][j+x-y]=1;
f[i][j+y-x]=1,g[i][j+y-x]=0;
}
for(int i=0;i<=100;++i)
if(f[cnt][100-i]) {print(cnt,i+100);break;}
printf("%llu ",ans[0].size());
for(unsigned i=0;i<ans[0].size();++i) printf("%d ",ans[0][i]);
printf("\n%llu ",ans[1].size());
for(unsigned i=0;i<ans[1].size();++i) printf("%d ",ans[1][i]);
return 0;
}

POJ1112 Team Them Up!的更多相关文章

  1. POJ1112 Team Them Up![二分图染色 补图 01背包]

    Team Them Up! Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 7608   Accepted: 2041   S ...

  2. OUC_OptKernel_oshixiaoxiliu_好题推荐

    poj1112 Team Them Up! 补图二分图+dp记录路径codeforces 256A Almost Arithmetical Progression dp或暴力 dp[i][j] = d ...

  3. 【poj1112】 Team Them Up!

    http://poj.org/problem?id=1112 (题目链接) 题意 将n个人分成两组,每个人有认识的人,要求每一组中的人互相认识,并且两组人数之差尽可能的小,求如何分. Solution ...

  4. Configure a VLAN on top of a team with NetworkManager (nmcli) in RHEL7

    SOLUTION VERIFIED September 13 2016 KB1248793 Environment Red Hat Enterprise Linux 7 NetworkManager ...

  5. Create a Team in RHEL7

    SOLUTION VERIFIED September 13 2016 KB2620131 Environment Red Hat Enterprise Linux 7 NetworkManager ...

  6. Team Leader 你不再只是编码, 来炖一锅石头汤吧

    h3{ color: #000; padding: 5px; margin-bottom: 10px; font-weight: bolder; background-color: #ccc; } h ...

  7. Configure bridge on a team interface using NetworkManager in RHEL 7

    SOLUTION IN PROGRESS February 29 2016 KB2181361 environment Red Hat Enterprise Linux 7 Teaming,Bridg ...

  8. BZOJ 4742: [Usaco2016 Dec]Team Building

    4742: [Usaco2016 Dec]Team Building Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 21  Solved: 16[Su ...

  9. 关于 feature team 的一些内容

    矩阵式管理,是常见的经典管理架构.其最早起源于美国的航空航天部门,然后被美国人带到了日本,然后被日本人带到了台湾,然后台湾人带到大陆...矩阵管理最典型的特征是,组织架构按职能与专业划分,项目由跨越部 ...

随机推荐

  1. Unity3d监听手机暂停与退出事件

    做移动互联网类型的开放,很多情况得考虑移动设备的暂停与退出时,做某些数据操作或UI. 1,退出事件,Unity3d,InPut就包含了: Input.GetKey(KeyCode.Escape) .  ...

  2. 计算点与x轴正半轴夹角atan2(double y,double x),返回弧度制(-PI,PI]

    精度比acos , asin 什么的高些. Parameters y Value representing the proportion of the y-coordinate. x Value re ...

  3. 【BZOJ3331】[BeiJing2013]压力 Tarjan求点双

    [BZOJ3331][BeiJing2013]压力 Description 如今,路由器和交换机构建起了互联网的骨架.处在互联网的骨干位置的核心路由器典型的要处理100Gbit/s的网络流量.他们每天 ...

  4. 【BZOJ4894】天赋 有向图生成树计数

    [BZOJ4894]天赋 Description 小明有许多潜在的天赋,他希望学习这些天赋来变得更强.正如许多游戏中一样,小明也有n种潜在的天赋,但有一些天赋必须是要有前置天赋才能够学习得到的.也就是 ...

  5. 4 Values whose Sum is 0(二分)

    4 Values whose Sum is 0 Time Limit: 15000MS   Memory Limit: 228000K Total Submissions: 21370   Accep ...

  6. Spring MVC的视图解析器

    一.视图解析器简介 在Spring MVC中,当Controller将请求处理结果放入到ModelAndView中以后,DispatcherServlet会根据ModelAndView选择合适的视图进 ...

  7. Win10 Edge浏览器 应用商店 IE浏览器 无法访问页面 0x8000FFFF 问题解决

  8. [Oracle]根据字段值全库搜索相关数据表和字段

    这个需求比较冷门,但对于在某些特定的情况下,还是会有这样的需要的.好在Oracle实现还比较方便,用存储过程则轻松实现. 查询字符串: create or replace procedure sear ...

  9. Virtualbox报错------> VirtualBox虚拟机下鼠标不正常的解决方法

    在Virtualbox虚拟机下,突然发现鼠标使用不正常.出现2个鼠标,一个是Ubuntu主机下面的鼠标,一个是Window7下的鼠标,但是Win7下的鼠标不可以看得到,但是点击鼠标左右键可以看到有反应 ...

  10. PHP 提高PHP性能的编码技巧以及性能优化

    0.用单引号代替双引号来包含字符串,这样做会更快一些.因为PHP会在双引号包围的字符串中搜寻变量,单引号则不会,注意:只有echo能这 么做,它是 一种可以把多个字符串当作参数的“函数”(译注:PHP ...