UVA 1627 Team them up!
https://cn.vjudge.net/problem/UVA-1627
题目
有n(n≤100)个人,把他们分成非空的两组,使得每个人都被分到一组,且同组中的人相互认识。要求两组的成员人数尽量接近。多解时输出任意方案,无解时输出No Solution。
例如,1认识2, 3, 5;2认识1, 3, 4, 5;3认识1, 2, 5,4认识1, 2, 3,5认识1, 2, 3, 4(注意4认识1但1不认识4),则可以分两组:{1,3,5}和{2,4}。
题解
不是互相认识的连边,然后保证一条边的两个人分到两个不同的组
一个连通分量的人可以存起来……那么类似于poj1417最后的dp部分
设$dp[i][j]$为前i个连通块,两组人数差为j时是否存在
因为j可能为负数,不方便迭代,于是改为设$dp[i][100+j]$
易证若差为j时存在,那么差为-j时也存在,于是最后只用枚举$dp[conn][100..100+n]$是否存在,然后按照dp相反的方向输出解(因为要看每一次的决策是什么)
AC代码
#include<bits/stdc++.h>
using namespace std; #define REP(r,x,y) for(register int r=(x); r<(y); r++)
#define PER(r,x,y) for(register int r=(x); r>(y); r--)
#define REPE(r,x,y) for(register int r=(x); r<=(y); r++)
#define PERE(r,x,y) for(register int r=(x); r>=(y); r--)
#ifdef sahdsg
#define DBG(...) printf(__VA_ARGS__)
#else
#define DBG(...) (void)0
#endif
int n;
int G[107][107];
bool tmp[107];
int v[107],conn=0,r[107];
int vis[107];
bool failed;
int dp[107][207];
int cho[107];
inline int signx(int x, int k) {
int ans=1;
int t=x+1; if(t>n) t=1;
vis[x]=k;
do {
if(G[x][t]) {
if(!vis[t])
ans-=signx(t,-k);
else if(vis[t]!=-k) {
failed = true;
return 0;
}
}
if(failed) return 0;
t++; if(t>n) t=1;
} while(t!=x);
return ans;
}
int ansarr[107][2], ansn[2]={0,0};
inline void anx(int x, int i) {
ansarr[ansn[i]++][i]=x;
int t=x+1; if(t>n) t=1;
vis[x]=-2;
do {
if(G[x][t] && vis[t]!=-2) {
anx(t, !i);
}
t++; if(t>n) t=1;
} while(t!=x);
}
int main() {
#ifdef sahdsg
freopen("in.txt","r",stdin);
#endif
int t; scanf("%d", &t);
while(0<t--) {
scanf("%d", &n); memset(G,0,sizeof G); memset(vis,0,sizeof vis); conn=0;
REPE(i,1,n) {
int v;
memset(tmp,0,sizeof tmp);
tmp[i]=1;
while(1) {
scanf("%d", &v);
if(v==0) break;
tmp[v]=1;
}
REPE(j,1,n) if(tmp[j]==0) G[i][j]=G[j][i]=1;
}
failed = false;
int a=0;
REPE(i,1,n) {
if(!vis[i]) {r[++conn]=i; v[conn]=signx(i,1);}
if(failed) {
goto _wa;
}
}
#define in(x) ((x)<=200 && (x)>=0)
memset(dp,0,sizeof dp);
dp[0][100]=1;
REPE(i,1,conn) {
REPE(j,100-n,100+n) {
if(in(j-v[i]) && dp[i-1][j-v[i]]) dp[i][j]=1;
else if(in(j+v[i]) && dp[i-1][j+v[i]]) dp[i][j]=1;
}
}
memset(ansn,0,sizeof ansn);
for(; a<=n; a++) {
if(dp[conn][100+a]) {
break;
}
}
PERE(i,conn,1) {
if(in(100+a-v[i]) && dp[i-1][100+a-v[i]]) a-=v[i],anx(r[i],0);
else if(in(100+a+v[i]) && dp[i-1][100+a+v[i]]) a+=v[i],anx(r[i],1);
}
#undef in
REPE(j,0,1) {
printf("%d", ansn[j]);
REP(i,0,ansn[j]) {
printf(" %d", ansarr[i][j]);
}
putchar('\n');
}
if(t) putchar('\n'); continue;
_wa:
puts("No solution"); if(t) putchar('\n'); continue;
}
return 0;
}
UVA 1627 Team them up!的更多相关文章
- 【暑假】[深入动态规划]UVa 1627 Team them up!
UVa 1627 Team them up! 题目: Team them up! Time Limit: 3000MS Memory Limit: Unknown 64bit IO Forma ...
- 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 ...
- UVa 1627 Team them up! (01背包+二分图)
题意:给n个分成两个组,保证每个组的人都相互认识,并且两组人数相差最少,给出一种方案. 析:首先我们可以知道如果某两个人不认识,那么他们肯定在不同的分组中,所以我们可以根据这个结论构造成一个图,如果两 ...
- UVA.540 Team Queue (队列)
UVA.540 Team Queue (队列) 题意分析 有t个团队正在排队,每次来一个新人的时候,他可以插入到他最后一个队友的身后,如果没有他的队友,那么他只能插入到队伍的最后.题目中包含以下操作: ...
- 【Uva 1627】Team them up!
[Link]: [Description] 给你n个人; 有一些人之间有认识关系 a认识b,b不一定认识a 让你把这n个人分成两组 使得这两组中的每一组: 组内的人与人之间都相互认识. 并且,使得两组 ...
- uva 540 - Team Queue(插队队列)
首发:https://mp.csdn.net/mdeditor/80294426 例题5-6 团体队列(Team Queue,UVa540) 有t个团队的人正在排一个长队.每次新来一个人时,如果他有队 ...
- UVA 540 Team Queue(模拟+队列)
题目代号:UVA 540 题目链接:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page ...
- UVa 540 Team Queue 【STL】
题意:给出t个团体,这t个团体排在一起,每次新来一个x排队,如果在整个的团体队列中,有x的队友,那么x排在它的队友的后面,如果他没有队友,则排在长队的队尾 求给出的每一个出队命令,输出出队的人的编号 ...
- UVA 540 Team Queue
思路:使用优先队列,按队伍出现的时刻和自身出现的时刻定义优先级,同时记录此时刻队列里是否有自己队伍的人,一开始没注意,wa了两发. #include<map> #include<qu ...
随机推荐
- WebUploader点击上传文件选择框会延迟几秒才会显示
accept: { title: 'Images', extensions: 'jpg,jpeg,png', mimeTypes: 'image/*' } 改为 accept: { title: 'I ...
- JavaScript-数字和字符串比较大小
JavaScript经常会比较字符串的大小,有的时候容易混淆,因此简单的梳理一下JavaScript字符串的比较: //1.数字比较 console.log('数字比较:' + (12 < 3) ...
- 前端性能优化(css动画篇)
正巧看到在送书,于是乎找了找自己博客上记录过的一些东西来及其无耻的蹭书了~~~ 小广告:更多内容可以看我的博客 最近拜读了一下html5rocks上几位大神写的一篇关于CSS3动画性能优化的文章,学到 ...
- 从.Net到Java学习第九篇——SpringBoot下Thymeleaf
从.Net到Java学习系列目录 Thymeleaf概述 Thymeleaf 是一个流行的模板引擎,该模板引擎采用java语言开发.模板引擎是一个技术名称,是跨领域平台的概念,在java语言体系下有模 ...
- 记录CentOS 7.4 上安装MySQL&MariaDB&Redis&Mongodb
记录CentOS 7.4 上安装MySQL&MariaDB&Redis&Mongodb 前段时间我个人Google服务器意外不能用,并且我犯了一件很低级的错误,直接在gcp讲服 ...
- (四)版本控制管理器之VSS
在上一篇<(二)版本控制管理器值CVS(下)>的文章中,我为大家介绍了CVS这个版本控制器,接下来我继续跟大家分享介绍下一个版本控制管理器--VSS,为什么要说这个版本控制器呢?早已过时的 ...
- DataSnap 多层返回数据集分析FireDAC JSON
采用服务器返回数据,一种是返回字符串数据例如JSON,跨平台跨语言,任何语言调用都支持兼容,类似WEBService. 第二种是紧密结合c++builder语言,传输DataSet,可以是Client ...
- c/c++ linux 进程间通信系列5,使用信号量
linux 进程间通信系列5,使用信号量 信号量的工作原理: 由于信号量只能进行两种操作等待和发送信号,即P(sv)和V(sv),他们的行为是这样的: P(sv):如果sv的值大于零,就给它减1:如果 ...
- UITableView编辑模式大全解
1.UITableView 的编辑模式 进入编辑模式 代码体现 // 设置 editing 属性 tableView?.editing = true // 这个设置的时候是有动画效果的 tableVi ...
- koa 路由配置
Koa 路由 路由(Routing)是由一个 URI(或者叫路径)和一个特定的 HTTP 方法(GET.POST 等) 组成的,涉及到应用如何响应客户端对某个网站节点的访问. 通俗的讲:路由就是根据不 ...