二分图【洛谷P2175】 小Z的游戏分队
P2175 小Z的游戏分队
小Z受不了寂寞,准备举办一次DOTA比赛,为了能让ACM班全部都参加比赛,他还特制了一张DOTA地图能够支持任意多人打任意多人。
现在问题来了,怎么把这么多人分成两队?小Z的想法是,每个人报上自己愿意同队的同学,接着小Z会按如下要求将所有人分为两队:
对任意同学甲,和同学甲同队的人,必须都是同学甲愿意同队的同学。
小Z希望两队的人数差尽量小,如果这种分组不存在,那么输出No solution。
先想判无解的情况。
因为分两个组,所以可以通过二分图染色判环。
那么按照不认识关系建边。
(我也不知道为什么想到了按照不认识的关系建边,可能是因为样例给的认识的太多我画不出那个图,喵喵喵~~)
然后因为可能会存在多个环,需要处理一下,统计每个环内两个颜色点分别的个数。
实测第9,10个点卡多个环。
code:
#include <iostream>
#include <cstdio>
#include <queue>
#include <cstring>
using namespace std;
inline int read(){
int sum=0,f=1; char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1; ch=getchar();}
while(ch>='0'&&ch<='9'){sum=(sum<<1)+(sum<<3)+ch-'0'; ch=getchar();}
return sum*f;
}
const int wx=3000;
int flag[wx][wx];
int num;
int n,tot;
int sjc[wx],zmj[wx][wx];
int head[wx],col[wx],in[wx],ed[wx],vis[wx],size[wx];
struct e{
int nxt,to;
}edge[wx*wx];
void add(int from,int to){
edge[++num].nxt=head[from];
edge[num].to=to;
head[from]=num;
}
queue<int > q;
bool bfs(){
for(int i=1;i<=n;i++){
if(!ed[vis[i]]&&size[vis[i]]>1){
ed[vis[i]]=1;
col[i]=1;
q.push(i);
}
}
while(q.size()){
int u=q.front(); q.pop();
for(int i=head[u];i;i=edge[i].nxt){
int v=edge[i].to;
if(col[v]==col[u])return false;
if(col[v])continue;
else {
col[v]=3-col[u];
q.push(v);
}
}
}
return true;
}
void dfs(int u){
size[vis[u]]++;
for(int i=head[u];i;i=edge[i].nxt){
int v=edge[i].to;
if(vis[v])continue;
vis[v]=vis[u];
dfs(v);
}
}
void dfs2(int u){
zmj[vis[u]][col[u]]++; sjc[u]=1;
for(int i=head[u];i;i=edge[i].nxt){
int v=edge[i].to;
if(vis[v]!=vis[u]||sjc[v])continue;
dfs2(v);
}
}
int main(){
n=read();
for(int i=1;i<=n;i++){
while(1){
int x; x=read();
if(!x)break;
flag[i][x]=1;
}
for(int j=1;j<=n;j++){
if(i!=j&&!flag[i][j]){
add(i,j); add(j,i);
// cout<<i<<" "<<j<<endl;
in[j]++; in[i]++;
}
}
}
for(int i=1;i<=n;i++){
if(!vis[i]){
vis[i]=++tot;
dfs(i);
}
}
if(!bfs())printf("No solution\n");
else{
int ans1=0,ans2=0;
memset(ed,0,sizeof ed);
for(int i=1;i<=n;i++){
if(!ed[vis[i]]&&size[vis[i]]>1){
ed[vis[i]]=1;
dfs2(i);
}
}
for(int i=1;i<=tot;i++){
if(size[i]==1){
if(ans1>ans2)ans2++;
else ans1++;
}
else {
if(ans1>ans2)ans2+=max(zmj[i][1],zmj[i][2]),ans1+=min(zmj[i][1],zmj[i][2]);
else ans1+=max(zmj[i][1],zmj[i][2]),ans2+=min(zmj[i][1],zmj[i][2]);
}
}
printf("%d %d\n",min(ans1,ans2),max(ans1,ans2));
}
// for(int i=1;i<=n;i++)printf("%d %d\n",i,col[i]);
return 0;
}
二分图【洛谷P2175】 小Z的游戏分队的更多相关文章
- Bzoj2038/洛谷P1494 小Z的袜子(莫队)
题面 Bzoj 洛谷 题解 考虑莫队算法,首先对询问进行分块(分块大小为\(sqrt(n)\)),对于同一个块内的询问,按照左端点为第一关键字,右端点为第二关键字排序.我们统计这个区间内相同的颜色有多 ...
- 洛谷 2186 小Z的栈函数
https://www.luogu.org/problem/show?pid=2186 题目描述 小Z最近发现了一个神奇的机器,这个机器的所有操作都是通过维护一个栈来完成的,它支持如下11个操作: N ...
- 洛谷——P2117 小Z的矩阵
P2117 小Z的矩阵 题目描述 小Z最近迷上了矩阵,他定义了一个对于一种特殊矩阵的特征函数G.对于N*N的矩阵A,A的所有元素均为0或1,则G(A)等于所有A[i][j]*A[j][i]的和对2取余 ...
- 洛谷P2188 小Z的 k 紧凑数
P2188 小Z的 k 紧凑数 题目描述 小 Z 在草稿纸上列出了很多数,他觉得相邻两位数字差的绝对值不超过 k 的整数特别奇特,称其为 k 紧凑数. 现在小 Z 想知道 [l,r] 内有多少个 k ...
- 洛谷—— P2117 小Z的矩阵
https://www.luogu.org/problemnew/show/2117 题目描述 小Z最近迷上了矩阵,他定义了一个对于一种特殊矩阵的特征函数G.对于N*N的矩阵A,A的所有元素均为0或1 ...
- 洛谷 P2117 小Z的矩阵
P2117 小Z的矩阵 题目描述 小Z最近迷上了矩阵,他定义了一个对于一种特殊矩阵的特征函数G.对于N*N的矩阵A,A的所有元素均为0或1,则G(A)等于所有A[i][j]*A[j][i]的和对2取余 ...
- [洛谷P2186] 小Z的栈函数
题目链接: 传送门 题目分析: 大模拟,先得存操作,然后再处理每个数-- 有一个小优化,在处理操作的时候顺便判一下最后栈里是不是有且仅有一个数,但A完了才想起来,所以就算了-- 总之就是个模拟题--没 ...
- 洛谷 2187 小Z的笔记
[题解] DP. 设f[i]表示前i个字母,保留第i个字母,最多可以保留多少个字母:设g[i]为当前字母为i的位置对应的f的最大值. 转移方程就是f[i]=max(f[i], g[j]+1) (j与 ...
- [洛谷P2107] 小Z的AK计划
题目类型:贪心,堆 传送门:>Here< 题意:给出\(N\)个房间,每个房间距离起点的距离为\(x[i]\),每个房间可以选择进去和不进去,如果进去了那么要\(t[i]\)秒后才能出来. ...
随机推荐
- 转:三思!大规模MySQL运维陷阱之基于MyCat的伪分布式架构
在微信公众号看到一篇关于mycat的文章,觉得分析的很不错,给大家分享一下 三思!大规模MySQL运维陷阱之基于MyCat的伪分布式架构 原文链接:https://mp.weixin.qq.com/s ...
- 转:利用UDEV服务解决RAC ASM存储设备名
利用UDEV服务解决RAC ASM存储设备名 好文转载,链接:http://www.askmaclean.com/archives/utilize-udev-resolve-11gr2-rac-asm ...
- django的settings.py设置static
DEBUG = True ################ STATICFILES ################ # A list of locations of additional stati ...
- openGL一些概念01
顶点数据: 顶点数据是一系列顶点的集合. 一个顶点(Vertex)是一个3d坐标的数据的集合. 而顶点数据是用顶点属性(Vertex Attribute)表示的,它可以包含任何我们想用的数据. (但是 ...
- DAY4-函数进阶
目录: 一.迭代器 二.生成器 三.面向过程编程 四.三元表达式.列表推导式.生成器表达式 五.第归与二分法 六.匿名函数 七.内置函数 练习 一.迭代器 一.迭代的概念 #迭代器即迭代的工具,那什么 ...
- C#高级参数ref的使用
ref关键字用于将方法内的变量改变后带出方法外.具体我们通过例子来说明: 例子中,将变量n1和n2交换了.如果没有加ref参数,由于没有swadDemo()方法没有返回值,调用后,n1和n2是不会交换 ...
- css水平居中(一)
第一种方法:使用text-align属性. 看到一篇博客,也不知道是不是我理解的问题,博客上说text-align可以是内联元素水平居中,我感觉这样的说法是不是有些不准确. text-align属性规 ...
- Python之POST登录测试
不解释,直接上代码: #!/usr/bin/env python # -*- encoding: utf-8 -*- """ @version: v1.0 @author ...
- Arduino 003 Ubuntu(Linux) 系统下,如何给板子烧写程序
Ubuntu/Linux 系统下,如何给Arduino板子烧写程序 使用的虚拟机软件:VMware 11 我的Ubuntu系统:Ubuntu 14.04.10 TLS Arduino 软件的版本:Ar ...
- Linux expect命令
一.简介 通过Shell可以实现简单的控制流功能,但是对于需要交互的场合则必须通过人工来干预,有时候我们可能会需要实现和交互程序如telnet服务器等进行交互的功能.而就使用来实现这种功能的工具.Ex ...