Coach(并查集)
Description
A programming coach has n students to teach. We know that n is divisible by 3. Let's assume that all students are numbered from 1 to n, inclusive.
Before the university programming championship the coach wants to split all students into groups of three. For some pairs of students we know that they want to be on the same team. Besides, if the i-th student wants to be on the same team with the j-th one, then the j-th student wants to be on the same team with the i-th one. The coach wants the teams to show good results, so he wants the following condition to hold: if the i-th student wants to be on the same team with the j-th, then the i-th and the j-th students must be on the same team. Also, it is obvious that each student must be on exactly one team.
Help the coach and divide the teams the way he wants.
Input
The first line of the input contains integers n and m(3 ≤ n ≤ 48,
. Then follow m lines, each contains a pair of integers ai, bi(1 ≤ ai < bi ≤ n) — the pair ai, bi means that students with numbers ai and bi want to be on the same team.
It is guaranteed that n is divisible by 3. It is guaranteed that each pair ai, bi occurs in the input at most once.
Output
If the required division into teams doesn't exist, print number -1. Otherwise, print
lines. In each line print three integers xi, yi, zi (1 ≤ xi, yi, zi ≤ n) — the i-th team.
If there are multiple answers, you are allowed to print any of them.
Sample Input
3 0
3 2 1
6 4
1 2
2 3
3 4
5 6
-1
3 3
1 2
2 3
1 3
3 2 1
题意:教练培训n个同学(n%3 = 0),要给他们分组,每3个人一组,要分n/3组,输入的m行中的x、y代表x想和y分一组,教练会根据他们的请求将他们分为一组,若最后分组不成功输出-1,否则一一输出各组同学的序号。 思路:先套并查集模板将可以分成一组的以邻接表的形式存起来,然后再判断,如果与i一组的人数大于3,说明分组不成功。具体看代码。
#include<stdio.h>
#include<string.h>
#include<queue>
using namespace std;
int n,m;
int gp[][];//gp[i][j]表示j与i可以分一组
int cnt[];//cnt[i]表示与i一组的人数
int vis[];
int set[];
queue<int>que[];
int find(int x)
{
if(set[x] != x)
set[x] = find(set[x]);
return set[x];
} int main()
{
scanf("%d %d",&n,&m);
int t,flag;
for(int i = ; i <= n; i++)
set[i] = i;
int u,v;
for(int i = ; i <= m; i++)
{
scanf("%d %d",&u,&v);
int uu = find(u);
int vv = find(v);
if(uu != vv)
set[uu] = vv;
}
for(int i = ; i <= n; i++)
{
cnt[i] = ;
t = find(i);
for(int j = ; j <= n; j++)
{
if(t == find(j))
{
gp[i][cnt[i]++] = j;
}
}
}//并查集,将所有可能分一组的存起来 memset(vis,,sizeof(vis));
flag = ;
for(int i = ; i <= n; i++)
{
if(cnt[i] > )//如果与i一组的人数大于3,不合法
{
flag = ;
continue;
}
if(vis[gp[i][]]) continue; else if(cnt[i] == )
que[].push(i);
else if(cnt[i] == )
que[].push(i);
else if(cnt[i] == )
que[].push(i); vis[gp[i][]] = ;
}
if(que[].size() < que[].size() || (que[].size()-que[].size())% !=)
flag = ; if(flag)
{
while(que[].size() > )
{
int sec = que[].front();
que[].pop();
printf("%d %d ",gp[sec][],gp[sec][]); int fir = que[].front();
que[].pop();
printf("%d\n",gp[fir][]);
} while(que[].size() > )
{
int fir = que[].front();
que[].pop();
printf("%d ",gp[fir][]); fir = que[].front();
que[].pop();
printf("%d ",gp[fir][]); fir = que[].front();
que[].pop();
printf("%d\n",gp[fir][]);
} while(que[].size() > )
{
int thi= que[].front();
que[].pop();
printf("%d %d %d\n",gp[thi][],gp[thi][],gp[thi][]);
}
}
else printf("-1\n"); return ;
}
Coach(并查集)的更多相关文章
- Codeforces Round #181 (Div. 2) B. Coach 带权并查集
B. Coach 题目连接: http://www.codeforces.com/contest/300/problem/A Description A programming coach has n ...
- BZOJ 4199: [Noi2015]品酒大会 [后缀数组 带权并查集]
4199: [Noi2015]品酒大会 UOJ:http://uoj.ac/problem/131 一年一度的“幻影阁夏日品酒大会”隆重开幕了.大会包含品尝和趣味挑战两个环节,分别向优胜者颁发“首席品 ...
- 关押罪犯 and 食物链(并查集)
题目描述 S 城现有两座监狱,一共关押着N 名罪犯,编号分别为1~N.他们之间的关系自然也极不和谐.很多罪犯之间甚至积怨已久,如果客观条件具备则随时可能爆发冲突.我们用"怨气值"( ...
- 图的生成树(森林)(克鲁斯卡尔Kruskal算法和普里姆Prim算法)、以及并查集的使用
图的连通性问题:无向图的连通分量和生成树,所有顶点均由边连接在一起,但不存在回路的图. 设图 G=(V, E) 是个连通图,当从图任一顶点出发遍历图G 时,将边集 E(G) 分成两个集合 T(G) 和 ...
- bzoj1854--并查集
这题有一种神奇的并查集做法. 将每种属性作为一个点,每种装备作为一条边,则可以得到如下结论: 1.如果一个有n个点的连通块有n-1条边,则我们可以满足这个连通块的n-1个点. 2.如果一个有n个点的连 ...
- [bzoj3673][可持久化并查集 by zky] (rope(可持久化数组)+并查集=可持久化并查集)
Description n个集合 m个操作 操作: 1 a b 合并a,b所在集合 2 k 回到第k次操作之后的状态(查询算作操作) 3 a b 询问a,b是否属于同一集合,是则输出1否则输出0 0& ...
- [bzoj3123][sdoi2013森林] (树上主席树+lca+并查集启发式合并+暴力重构森林)
Description Input 第一行包含一个正整数testcase,表示当前测试数据的测试点编号.保证1≤testcase≤20. 第二行包含三个整数N,M,T,分别表示节点数.初始边数.操作数 ...
- 【BZOJ-3673&3674】可持久化并查集 可持久化线段树 + 并查集
3673: 可持久化并查集 by zky Time Limit: 5 Sec Memory Limit: 128 MBSubmit: 1878 Solved: 846[Submit][Status ...
- Codeforces 731C Socks 并查集
题目:http://codeforces.com/contest/731/problem/C 思路:并查集处理出哪几堆袜子是同一颜色的,对于每堆袜子求出出现最多颜色的次数,用这堆袜子的数目减去该值即为 ...
随机推荐
- thinkphp 常见问题
0.写在最前面的不断更新 (1)trace不起作用 A:必须要输出到模板,才会有trace信息 (2)提示“您浏览的页面暂时发生了错误!请稍后再试-” A:检查控制器(看看能进到控制器没有,设断点输出 ...
- Java中的I/O流
import java.io.*//生成代表输入流的对象fis=new FileInputStream("e:/src/from.txt") //生成代表输出流的对象 fos=ne ...
- 程序员带你十天快速入门Python,玩转电脑软件开发(四)
本系列文章立志于从一个已经习得一门编程语言的基础之上,全面介绍Python的相关开发过程和相关经验总结.本篇文章主要是基于上一篇的程序员带你十天快速入门Python,玩转电脑软件开发(三)的基础之上, ...
- Oracle 特殊字符模糊查询的方法
最近在写DAO层的时候,遇到一个问题,就是使用like进行模糊查询时,输入下划线,无法精确查到数据,而是返回所有的数据. 这让我很好奇,百度之后才发现,原来是因为有些特殊字符需要进行转义才可以进行查询 ...
- 安卓Intent(显式)
1.Intent是Android程序中各组件之间交互的重要方式,一般可用于启动活动.启动服务.以及发送广播等场景,这里先对活动进行说明Intent的一些作用. 2.Intent的用法大致可分为,显式I ...
- javascript的面向对象编程
面象对象编程技术的核心理念:封装.继承.多态:在一些主流的高级编程语言中,比如:C#,VB.NET,JAVA,PHP等都是很容易实现的,而如果要在javascript中实现面象对象编程,可就不那么直接 ...
- android中ListView控件
今天学习了ListView控件和页面跳转,下面大致介绍下: 第一步:创建显示内容的文件vlist.xml: <?xml version="1.0" encoding=&quo ...
- 国内最简单的短视频SDK
最近阿里百川和趣拍一起合作推出了一个短视频SDK.之前很多厂商可能都是用的Vitamio的短视频SDK.之后我考察过,也做过一些调查,发现Vitamio真的奇贵无比,屌丝公司根本用不起,阿里和趣拍这下 ...
- SGU 296.Sasha vs. Kate(贪心)
题意: 给出长度为n(<=1000)的一个数.输出删掉k个数字后的最大值. Solution: 简单贪心. s[i]代表数字s的第i位. 从前往后第一个满足s[i]>s[i-1]的位置,最 ...
- yii2源码学习笔记(十五)
这几天有点忙今天好些了,继续上次的module来吧 /** * Returns the directory that contains the controller classes according ...