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

Description

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 the 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 a team in any order.

Sample Input

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

3 1 3 5
2 2 4

Source


题意:

白书

一个N个节点的有向图,将节点分成两个集合,满足以下四个条件:

1。每个节点属于其中一个集合

2。每个集合至少有一个节点

3。集合里的每一个节点都有边连向同一个集合里的其他点

4。被分成的两个集合的大小要尽量接近


如果两人不互相认识,则一定要被分在不同集合里
所以建原图的补图,也就是两个不互相认识的人连一条边,求连通分量
对每个cc二染色,失败的话No solution,否则相同颜色的人一定加在一个集合里
每个cc相当于物品,原题就是求一些物品分两组,使他们的差值最小,01背包
 
让cc的权值为两个颜色的人数之差
f[i][j+n]表示前i个cc,第一组比第二组多j是否可行
普通的状态方程和更新写法都可以,打印路径也没必要记录pa,用状态转移方程判断就可以
也可以装一个N/2的背包
 
PS:1.一定注意第二维+n
  2.POJ坑人数组越界爆WA
  3.变量一大片记不过来系列
//更新写法
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
using namespace std;
const int N=;
inline int read(){
char c=getchar();int x=,f=;
while(c<''||c>''){if(c=='-')f=-; c=getchar();}
while(c>=''&&c<=''){x=x*+c-''; c=getchar();}
return x*f;
}
int n,g[N][N];
struct edge{
int v,ne;
}e[N*N<<];
int h[N],cnt=;
void ins(int u,int v){
cnt++;
e[cnt].v=v;e[cnt].ne=h[u];h[u]=cnt;
cnt++;
e[cnt].v=u;e[cnt].ne=h[v];h[v]=cnt;
}
int col[N],cc=,tm[N][][N],p[N][];//team p
bool dfs(int u,int c){
col[u]=c;
tm[cc][c][++p[cc][c]]=u;
for(int i=h[u];i;i=e[i].ne){
int v=e[i].v;
if(col[u]==col[v]) return false;
if(!col[v]&&!dfs(v,-c)) return false;
}
return true;
}
int w[N];
bool init(){
for(int i=;i<=n;i++) if(!col[i]){
cc++;
if(!dfs(i,)) return false;
w[cc]=p[cc][]-p[cc][];//printf("w %d %d\n",cc,w[cc]);
}
return true;
}
int f[N][N<<],pa[N][N<<]; void dp(){
f[][+n]=;
for(int i=;i<cc;i++)
for(int j=-n;j<=n;j++)
if(f[i][j+n]) f[i+][j+n+w[i+]]=f[i+][j+n-w[i+]]=;
} int t1[N],t2[N],c1,c2;
void print(int s){
for(int i=cc;i>=;i--){
int flag=;
if(f[i-][s+n-w[i]]){flag=;s-=w[i];}//the color for t1
else{flag=;s+=w[i];}
//printf("s %d\n",s);
for(int j=;j<=p[i][flag];j++) t1[++c1]=tm[i][flag][j];
flag=-flag;
for(int j=;j<=p[i][flag];j++) t2[++c2]=tm[i][flag][j];
} printf("%d ",c1);
for(int i=;i<=c1;i++) printf("%d ",t1[i]);
printf("\n%d ",c2);
for(int i=;i<=c2;i++) printf("%d ",t2[i]);
} int main(int argc, const char * argv[]) {
n=read();
for(int i=;i<=n;i++){
int v=read();
while(v!=) g[i][v]=,v=read();
}
for(int i=;i<=n;i++)
for(int j=i+;j<=n;j++)
if(g[i][j]==||g[j][i]==) ins(i,j);
if(!init()||n==) printf("No solution");
else{
dp();
for(int i=;i<=n;i++){
//printf("hi %d %d %d\n",cc,n+i,n-i);
if(f[cc][n+i]) {print(i);break;}
if(f[cc][n-i]) {print(-i);break;}
}
}
return ;
}
//普通
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
using namespace std;
const int N=;
inline int read(){
char c=getchar();int x=,f=;
while(c<''||c>''){if(c=='-')f=-; c=getchar();}
while(c>=''&&c<=''){x=x*+c-''; c=getchar();}
return x*f;
}
int n,g[N][N];
struct edge{
int v,ne;
}e[N*N<<];
int h[N],cnt=;
void ins(int u,int v){
cnt++;
e[cnt].v=v;e[cnt].ne=h[u];h[u]=cnt;
cnt++;
e[cnt].v=u;e[cnt].ne=h[v];h[v]=cnt;
}
int col[N],cc=,tm[N][][N],p[N][];//team p
bool dfs(int u,int c){
col[u]=c;
tm[cc][c][++p[cc][c]]=u;
for(int i=h[u];i;i=e[i].ne){
int v=e[i].v;
if(col[u]==col[v]) return false;
if(!col[v]&&!dfs(v,-c)) return false;
}
return true;
}
int w[N];
bool init(){
for(int i=;i<=n;i++) if(!col[i]){
cc++;
if(!dfs(i,)) return false;
w[cc]=p[cc][]-p[cc][];//printf("w %d %d\n",cc,w[cc]);
}
return true;
}
int f[N][N<<],pa[N][N<<]; void dp2(){
f[][+n]=;
for(int i=;i<=cc;i++)
for(int j=-n;j<=n;j++){
if(n+j-w[i]>=&&f[i-][n+j-w[i]]){
f[i][j+n]=;
pa[i][j+n]=;//zheng zhe fen pei
}else if(n+j+w[i]<=*n&&f[i-][n+j+w[i]]){
f[i][j+n]=;
pa[i][j+n]=-;
}
//printf("f %d %d %d\n",i,j,f[i][j]);
}
} int t1[N],t2[N],c1,c2; void print2(int s){
for(int i=cc;i>=;i--){
int flag=;
if(pa[i][s+n]==) {flag=;s-=w[i];}
else {flag=;s+=w[i];} for(int j=;j<=p[i][flag];j++) t1[++c1]=tm[i][flag][j];
flag=-flag;
for(int j=;j<=p[i][flag];j++) t2[++c2]=tm[i][flag][j];
}
printf("%d ",c1);
for(int i=;i<=c1;i++) printf("%d ",t1[i]);
printf("\n%d ",c2);
for(int i=;i<=c2;i++) printf("%d ",t2[i]);
} int main(int argc, const char * argv[]) {
n=read();
for(int i=;i<=n;i++){
int v=read();
while(v!=) g[i][v]=,v=read();
}
for(int i=;i<=n;i++)
for(int j=i+;j<=n;j++)
if(g[i][j]==||g[j][i]==) ins(i,j);
if(!init()||n==) printf("No solution");
else{
dp2(); for(int i=;i<=n;i++){
//printf("hi %d %d %d\n",cc,n+i,n-i);
if(f[cc][n+i]) {print2(i);break;}
if(f[cc][n-i]) {print2(-i);break;}
}
}
return ;
}
 
 
 
 

POJ1112 Team Them Up![二分图染色 补图 01背包]的更多相关文章

  1. POJ2942 Knights of the Round Table[点双连通分量|二分图染色|补图]

    Knights of the Round Table Time Limit: 7000MS   Memory Limit: 65536K Total Submissions: 12439   Acce ...

  2. POJ 1112 Team Them Up! 二分图判定+01背包

    题目链接: http://poj.org/problem?id=1112 Team Them Up! Time Limit: 1000MSMemory Limit: 10000K 问题描述 Your ...

  3. POJ2942 Knights of the Round Table【Tarjan点双联通分量】【二分图染色】【补图】

    LINK 题目大意 有一群人,其中有一些人之间有矛盾,现在要求选出一些人形成一个环,这个环要满足如下条件: 1.人数大于1 2.总人数是奇数 3.有矛盾的人不能相邻 问有多少人不能和任何人形成任何的环 ...

  4. HDU 5313 Bipartite Graph(二分图染色+01背包水过)

    Problem Description Soda has a bipartite graph with n vertices and m undirected edges. Now he wants ...

  5. 【POJ 2942】Knights of the Round Table(点双连通分量,二分图染色)

    圆桌会议必须满足:奇数个人参与,相邻的不能是敌人(敌人关系是无向边). 求无论如何都不能参加会议的骑士个数.只需求哪些骑士是可以参加的. 我们求原图的补图:只要不是敌人的两个人就连边. 在补图的一个奇 ...

  6. POJ 2942Knights of the Round Table(tarjan求点双+二分图染色)

    Time Limit: 7000MS   Memory Limit: 65536K Total Submissions: 13954   Accepted: 4673 Description Bein ...

  7. poj2942 点-双联通+二分图染色

    题意:有一群骑士要坐在一个圆形的桌子上,他们之间有些人相互讨厌,所以不能挨着,要求算出一次也不能坐在桌子上的人,每次会议桌子必须奇数个人,一个人不能开会 题解:可以先建一个补图,要满足题目条件我们只要 ...

  8. [多校联考2019(Round 5 T2)]蓝精灵的请求(二分图染色+背包)

    [多校联考2019(Round 5)]蓝精灵的请求(二分图染色+背包) 题面 在山的那边海的那边住着 n 个蓝精灵,这 n 个蓝精灵之间有 m 对好友关系,现在蓝精灵们想要玩一个团队竞技游戏,需要分为 ...

  9. LUOGU P5061 秘密任务(背包+二分图染色)

    传送门 解题思路 \(orz\)出题人的神仙做法.本蒟蒻看不懂,就水个求补图再二分图染色的方法来\(%1%\)出题人. 首先我们对图中\(m\)个关系连边,发现这样是没法做的,因为我们最后要关注的是谁 ...

随机推荐

  1. 背水一战 Windows 10 (24) - MVVM: 通过 Binding 或 x:Bind 结合 Command 实现,通过非 ButtonBase 触发命令

    [源码下载] 背水一战 Windows 10 (24) - MVVM: 通过 Binding 或 x:Bind 结合 Command 实现,通过非 ButtonBase 触发命令 作者:webabcd ...

  2. Newtonsoft.Json异常处理

    var resultStr="{\"Success\":false,\"Data\":1}"; GetRequestPriceRendaIn ...

  3. 利用节点更改table内容

    <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title> new document ...

  4. VS 快捷键

    项目相关的快捷键 Ctrl + Shift + B = 生成项目 Ctrl + Alt + L = 显示Solution Explorer(解决方案资源管理器) Shift + Alt+ C = 添加 ...

  5. C#中JSON序列化和反序列化

    有一段时间没有到博客园写技术博客了,不过每天逛逛博客园中大牛的博客还是有的,学无止境…… 最近在写些调用他人接口的程序,用到了大量的JSON.XML序列化和反序列化,今天就来总结下json的序列化和反 ...

  6. [deviceone开发]-一个固定列,可以上下左右滑动的表格示例

    一.简介 一个类型table的例子,第一列和第二列可以固定,剩下的后面的很多列都可以左右滑动,也可以上下滑动,这种需求一般是为了展示多列表格数据.这个例子是通过二大部分: 左边是一个普通的listvi ...

  7. 理解CSV文件以及ABAP中的相关操作

    在很多ABAP开发中,我们使用CSV文件,有时候,关于CSV文件本身的一些问题使人迷惑.它仅仅是一种被逗号分割的文本文档吗? 让我们先来看看接下来可能要处理的几个相关组件的词汇的语义. Separat ...

  8. App Store2016年最新审核规则

    为App Store开发程序,开发者必须遵守 Program License Agreement (PLA).人机交互指南(HIG)以及开发者和苹果签订的任何协议和合同. 以下规则和示例旨在帮助开发者 ...

  9. SharePoint 2013 Ajax 造成页面无法编辑

    1.如下图,在编辑页面的时候,出现如下错误“此网页自上次打开后已被修改,必须再次打开该网页”,页面上没有什么特别的设置,就是default.aspx: 2.编辑之前页面,只有一个内容编辑器部件,和若干 ...

  10. Android开发学习——打电话应用

    打电话应用 system/app/phone.apk  这个是打电话应用,这个Java API 不允许应用级程序员改写,系统级才可以 system/app/dialer.apk  这个是拨号器应用,可 ...