POJ 1112 Team Them Up! DP
来源:互联网 发布:小米数据迁移到苹果 编辑:程序博客网 时间:2024/06/06 05:34
题目大意:
现有n个人,现把他们分成两只队伍,要满足1、任何一个人有且仅属于一只队伍;2、队伍不能为空;3、队伍内的人互相认识;4、两只队伍人数尽量接近。现在给你这些人的认识关系,求一种合理的分队方式,如果没有输出No solution。
很有意思的DP,从“认识”考虑是困难的,但是两个人,如果他们不能互相认识,那么他们必然属于两个不同的组。我们用不认识的关系建边,进行奇偶染色,如果染色冲突,那么肯定无解。如果染色成功,我们可以把这个连通块的人分为两个部分。这样操作后,等于把人分为了若干类物品,每个物品有两个权。你每个物品必须选且只能选一个权,最后使得这个权和尽量接近所有权和的一半。而这个模型,是很好解决的。
#include<cstdio>#include<cstring>#include<vector>#include<queue>#include<cmath>#include<cctype>#include<string>#include<algorithm>#include<iostream>#include<ctime>#include<map>#include<set>using namespace std;#define MP(x,y) make_pair((x),(y))#define PB(x) push_back(x)typedef long long LL;//typedef unsigned __int64 ULL;/* ****************** */const int INF=100011122;const double INFF=1e100;const double eps=1e-8;const LL mod=20120427;const int NN=105;const int MM=1000010;/* ****************** */struct G{ int v,next;}E[NN*NN*2];int p[NN],T;void add(int u,int v){ E[T].v=v; E[T].next=p[u]; p[u]=T++;}int color[NN];int lei[NN];bool mat[NN][NN];bool dp[NN][NN];int pre[NN][NN];bool xuan[NN][2];bool fg;struct node{ int x,y;}a[NN];void dfs(int u,int lll){ int i,v; for(i=p[u];i+1;i=E[i].next) { v=E[i].v; if(color[v]==-1) { color[v]=1-color[u]; lei[v]=lll; if(color[v]==1) a[lll].x++; else a[lll].y++; dfs(v,lll); } else if(color[v]==color[u]) fg=true; }}void FF(int tol,int zt,int n){ int i,j; memset(xuan,false,sizeof(xuan)); j=zt; for(i=tol;i>=1;i--) { if(pre[i][j]==1) { xuan[i][1]=true; j=j-a[i].x; } else { xuan[i][0]=true; j=j-a[i].y; } } printf("%d",zt); for(i=1;i<=n;i++) { if(xuan[ lei[i] ][ color[i] ]) printf(" %d",i); } puts(""); printf("%d",n-zt); for(i=1;i<=n;i++) { if(!xuan[ lei[i] ][ color[i] ]) printf(" %d",i); } puts("");}int main(){ int n,i,j,t,tol; while(scanf("%d",&n)!=EOF) { memset(p,-1,sizeof(p)); T=0; memset(mat,false,sizeof(mat)); for(i=1;i<=n;i++) { while(1) { scanf("%d",&t); if(t==0)break; mat[i][t]=true; } } for(i=1;i<=n;i++) for(j=i+1;j<=n;j++) { if(!mat[i][j] || !mat[j][i]) { add(i,j); add(j,i); } } memset(color,-1,sizeof(color)); fg=false; tol=0; for(i=1;i<=n && !fg;i++) { if(color[i]==-1) { tol++; color[i]=1; lei[i]=tol; a[tol].x=1; a[tol].y=0; dfs(i,tol); } } if(fg) { puts("No solution"); continue; } memset(dp,false,sizeof(dp)); dp[0][0]=true; for(i=0;i<tol;i++) for(j=0;j<=n/2;j++) if(dp[i][j]) { dp[i+1][ j+a[i+1].x ]=true; pre[i+1][ j+a[i+1].x ]=1; dp[i+1][ j+a[i+1].y ]=true; pre[i+1][ j+a[i+1].y ]=0; } for(i=n/2;i>=1;i--) { if(dp[tol][i]) { FF(tol,i,n); break; } } if(i==0) puts("No solution"); } return 0;}
0 0
- 图论+dp poj 1112 Team Them Up!
- POJ 1112 Team Them Up! DP
- POJ 1112 Team Them Up
- poj 1112 Team Them Up!
- POJ 1112 Team Them Up!
- POJ 1112 Team Them Up!
- Poj 1112 Team Them Up!
- poj 1112 Team Them Up!(建图+dp)
- poj 1112 Team Them Up! 二分图染色+dp
- poj 1112 Team Them Up! (补图+dp)
- 【POJ 1112】Team Them Up!(补图+dp(背包))
- POJ 1112 Team Them Up! 笔记
- POJ 1112 Team Them Up! (二分图染色+连通分量+DP)
- poj 1112 二部图判定+背包(team them up)
- poj1112 Team Them Up!
- 1627 - Team them up!
- poj1112 Team Them Up!
- Team them up! UVA
- Linux等待队列使用步骤
- Wxpython ImportError DLL load failed: %1 不是有效的 Win32 应用程序
- iBATIS、Hibernate跟JPA 简介与对比
- 70.windbg---!pool
- 通过云片网实现短信以及验证码的发送
- POJ 1112 Team Them Up! DP
- 失眠,何其苦也!
- Effective c++ 条款28: 划分全局名字空间
- poj 3253Fence Repair--动态规划
- __proc_info_begin->__proc_info_end
- 如何关闭iOS中键盘自动大写
- 使用putty中的pscp在windows主机和Linux服务器之间传递文件
- 【求证明】【特殊的哈密顿回路】旅行
- hdu3709 Balanced Number