POJ1112 Team Them Up![二分图染色 补图 01背包]
| Time Limit: 1000MS | Memory Limit: 10000K | |||
| Total Submissions: 7608 | Accepted: 2041 | Special Judge | ||
Description
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
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
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。被分成的两个集合的大小要尽量接近
//更新写法
#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背包]的更多相关文章
- POJ2942 Knights of the Round Table[点双连通分量|二分图染色|补图]
Knights of the Round Table Time Limit: 7000MS Memory Limit: 65536K Total Submissions: 12439 Acce ...
- POJ 1112 Team Them Up! 二分图判定+01背包
题目链接: http://poj.org/problem?id=1112 Team Them Up! Time Limit: 1000MSMemory Limit: 10000K 问题描述 Your ...
- POJ2942 Knights of the Round Table【Tarjan点双联通分量】【二分图染色】【补图】
LINK 题目大意 有一群人,其中有一些人之间有矛盾,现在要求选出一些人形成一个环,这个环要满足如下条件: 1.人数大于1 2.总人数是奇数 3.有矛盾的人不能相邻 问有多少人不能和任何人形成任何的环 ...
- HDU 5313 Bipartite Graph(二分图染色+01背包水过)
Problem Description Soda has a bipartite graph with n vertices and m undirected edges. Now he wants ...
- 【POJ 2942】Knights of the Round Table(点双连通分量,二分图染色)
圆桌会议必须满足:奇数个人参与,相邻的不能是敌人(敌人关系是无向边). 求无论如何都不能参加会议的骑士个数.只需求哪些骑士是可以参加的. 我们求原图的补图:只要不是敌人的两个人就连边. 在补图的一个奇 ...
- POJ 2942Knights of the Round Table(tarjan求点双+二分图染色)
Time Limit: 7000MS Memory Limit: 65536K Total Submissions: 13954 Accepted: 4673 Description Bein ...
- poj2942 点-双联通+二分图染色
题意:有一群骑士要坐在一个圆形的桌子上,他们之间有些人相互讨厌,所以不能挨着,要求算出一次也不能坐在桌子上的人,每次会议桌子必须奇数个人,一个人不能开会 题解:可以先建一个补图,要满足题目条件我们只要 ...
- [多校联考2019(Round 5 T2)]蓝精灵的请求(二分图染色+背包)
[多校联考2019(Round 5)]蓝精灵的请求(二分图染色+背包) 题面 在山的那边海的那边住着 n 个蓝精灵,这 n 个蓝精灵之间有 m 对好友关系,现在蓝精灵们想要玩一个团队竞技游戏,需要分为 ...
- LUOGU P5061 秘密任务(背包+二分图染色)
传送门 解题思路 \(orz\)出题人的神仙做法.本蒟蒻看不懂,就水个求补图再二分图染色的方法来\(%1%\)出题人. 首先我们对图中\(m\)个关系连边,发现这样是没法做的,因为我们最后要关注的是谁 ...
随机推荐
- 背水一战 Windows 10 (15) - 动画: 缓动动画
[源码下载] 背水一战 Windows 10 (15) - 动画: 缓动动画 作者:webabcd 介绍背水一战 Windows 10 之 动画 缓动动画 - easing 示例演示缓动(easing ...
- 动态加载js和css
开发过程中经常需要动态加载js和css,今天特意总结了一下常用的方法. 1.动态加载js 方法一:动态加载js文件 // 动态加载js脚本文件 function loadScript(url) { v ...
- C++_系列自学课程_第_8_课_指针和引用_《C++ Primer 第四版》
C语言最富有迷幻色彩的部分当属指针部分,无论是指针的定义还是指针的意义都可算是C语言中最复杂的内容.指针不但提供给了程序员直接操作硬件部分的操作接口,还提供给了程序员更多灵活的用法.C++继承这一高效 ...
- POJ 2115 C Looooops扩展欧几里得
题意不难理解,看了后就能得出下列式子: (A+C*x-B)mod(2^k)=0 即(C*x)mod(2^k)=(B-A)mod(2^k) 利用模线性方程(线性同余方程)即可求解 模板直达车 #incl ...
- 【Java学习系列】第1课--Java环境搭建和demo运行
本文地址 分享提纲: 1. java环境的搭建 2. java demo代码运行 3.参考文档 本人是PHP开发者,一直感觉Java才是程序的王道(应用广,科班出身),所以终于下决心跟一跟. 主要是给 ...
- git的诞生
Git的诞生 很多人都知道,Linus在1991年创建了开源的Linux,从此,Linux系统不断发展,已经成为最大的服务器系统软件了. Linus虽然创建了Linux,但Linux的壮大是靠全世 ...
- 高性能 Socket 组件 HP-Socket v3.2.1 正式发布
HP-Socket 是一套通用的高性能 TCP/UDP Socket 组件,包含服务端组件.客户端组件和 Agent 组件,广泛适用于各种不同应用场景的 TCP/UDP 通信系统,提供 C/C++.C ...
- 理解 OpenStack 高可用(HA)(5):RabbitMQ HA
本系列会分析OpenStack 的高可用性(HA)概念和解决方案: (1)OpenStack 高可用方案概述 (2)Neutron L3 Agent HA - VRRP (虚拟路由冗余协议) (3)N ...
- 使用SQLServer同义词和SQL邮件,解决发布订阅中订阅库丢失数据的问题
最近给客户做了基于SQLServer的发布订阅的“读写分离”功能,但是某些表数据很大,经常发生某几条数据丢失的问题,导致订阅无法继续进行.但是每次发现问题重新做一次发布订阅又非常消耗时间,所以还得根据 ...
- kafkaspot在ack机制下如何保证内存不溢
新浪微博:intsmaze刘洋洋哥. storm框架中的kafkaspout类实现的是BaseRichSpout,它里面已经重写了fail和ack方法,所以我们的bolt必须实现ack机制,就可以 ...