题目链接:http://codeforces.com/problemset/problem/300/B

题目意思:给出n个students(n%3 = 0),编号依次为1~n,接下来有m行,每行有两个数:a和b(1<=a, b <= n),表示号码a的人想和号码b的人一起组队。但最终每一组的人最多只能为3个,至于组里只有2个或根本不成组的人可以通过组队变成3个人。问最后每组是否恰好为3人(包括原来不需要组队和组队后的情况),是则输出每组人的编号,否则输出-1。

一开始做的时候觉得像并查集,后来觉得做起来特别复杂,看了看tutorial,知道哪些情况为输出-1的:

情况1:组里面超过3人    情况2:2人组人数 > 1人组的人数(不成组)

根据这样硬用并查集来做,代码量非一般多!!!这就是不会算法的悲剧咯~~~

我的思路:

先用并查集来连边,保证大编号的指向最小编号的。

接着统计一人组,二人组,三人组的人数(分别为c1,c2,c3),以判断结果为-1的两种情况。

最后依次输出: 二人组 + 一人组,三人组,一人组 (除了三人组的情况其他两种都要组合)

(以后学好dfs一定要写条简短的代码,呜呜呜~~~整个晚上没了)

 #include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
using namespace std; const int maxn = + ;
int res[maxn], cnt[maxn], vis[maxn], vis1[maxn], vis2[maxn]; int find(int x)
{
while (x != res[x])
x = res[x];
return x;
} void merge(int x, int y)
{
int fx = find(x);
int fy = find(y);
if (fx > fy)
res[fx] = fy;
else
res[fy] = fx;
} int main()
{
int n, m, i, j, k, a, b;
while (scanf("%d%d", &n, &m) != EOF)
{
for (i = ; i <= n; i++)
res[i] = i;
for (i = ; i < m; i++)
{
scanf("%d%d", &a, &b);
merge(a, b);
}
memset(vis, , sizeof(vis));
memset(vis1, , sizeof(vis1));
memset(cnt, , sizeof(cnt));
int flag, c2, c1, c3, f;
c1 = c2 = c3 = ;
for (i = ; i <= n; i++)
{
flag = ;
if (res[i] == i)
{
f = ;
for (j = i+; j <= n; j++)
{
if (res[j] == i)
{
cnt[i]++;
f = ; // 1 p num 的标记
}
}
if (cnt[i] == ) // 3 p num
c3++;
if (cnt[i] == ) // 2 p num
{
c2++;
vis1[i] = ;
}
if (cnt[i] >= ) // 组里的人多于3个
flag = ;
if (!f) // 1 p num
{
vis[i] = ;
c1++;
}
}
if (!flag)
break;
}
if (c2 > c1 || !flag)
printf("-1\n");
else
{
memset(vis2, , sizeof(vis2));
for (i = ; i <= n; i++) // 2 p num + 1 p num
{
if (res[i] == i && vis1[i]) // vis1[i] 保证是2 p num
{
printf("%d ", i);
vis2[i] = ; // sign used
for (j = i+; j <= n; j++)
{
if (!vis[j] && res[j] == i) // !vis[j]:保证先输出2 p num的人
{
vis2[j] = ;
printf("%d ", j);
for (k = ; k <= n; k++) // 1 p
{
if (res[k] == k && vis[k] && !vis2[k]) // vis[k]:1 p num 的人
{
printf("%d\n", k);
vis2[k] = ;
c1--; // 每输出一次减去一个1 p num的人
break;
}
}
}
}
}
}
for (i = ; i <= n; i++) // 3 p num
{
if (res[i] == i && !vis1[i] && !vis[i]) // !vis1[i]:保证不是2 p num;!vis[i]:保证不是1 p num
{
for (j = i; j <= n; j++)
{
if (res[j] == i && !vis[j])
{
printf("%d ", j);
vis2[j] = ;
}
}
printf("\n");
}
}
int count = ;
for (i = ; i <= n && c1; i++) // 剩下的 1 p num的人,每3个人合成1组
{
if (!vis2[i])
{
printf("%d ", i);
c1--;
count++;
if (count % == )
printf("\n");
}
}
}
}
return ;
}

codeforces B. Coach 解题报告的更多相关文章

  1. codeforces 31C Schedule 解题报告

    题目链接:http://codeforces.com/problemset/problem/31/C 题目意思:给出 n 个 lessons 你,每个lesson 有对应的 起始和结束时间.问通过删除 ...

  2. codeforces 499B.Lecture 解题报告

    题目链接:http://codeforces.com/problemset/problem/499/B 题目意思:给出两种语言下 m 个单词表(word1, word2)的一一对应,以及 profes ...

  3. codeforces 495C. Treasure 解题报告

    题目链接:http://codeforces.com/problemset/problem/495/C 题目意思:给出一串只有三种字符( ')','(' 和 '#')组成的字符串,每个位置的这个字符 ...

  4. codeforces 490B.Queue 解题报告

    题目链接:http://codeforces.com/problemset/problem/490/B 题目意思:给出每个人 i 站在他前面的人的编号 ai 和后面的人的编号 bi.注意,排在第一个位 ...

  5. CodeForces 166E -Tetrahedron解题报告

    这是本人写的第一次博客,学了半年的基础C语言,初学算法,若有错误还请指正. 题目链接:http://codeforces.com/contest/166/problem/E E. Tetrahedro ...

  6. codeforces 489A.SwapSort 解题报告

    题目链接:http://codeforces.com/problemset/problem/489/A 题目意思:给出一个 n 个无序的序列,问能通过两两交换,需要多少次使得整个序列最终呈现非递减形式 ...

  7. codeforces 485A.Factory 解题报告

    题目链接:http://codeforces.com/problemset/problem/485/A 题目意思:给出 a 和 m,a 表示第一日的details,要求该日结束时要多生产 a mod ...

  8. codeforces 483A. Counterexample 解题报告

    题目链接:http://codeforces.com/problemset/problem/483/A 题目意思:给出一个区间 [l, r],要从中找出a, b, c,需要满足 a, b 互质,b, ...

  9. codeforces 479C Exams 解题报告

    题目链接:http://codeforces.com/problemset/problem/479/C 题目意思:简单来说,就是有个人需要通过 n 门考试,每场考试他可以选择ai, bi 这其中一个时 ...

随机推荐

  1. BZOJ1003物流運輸 DP + SPFA

    @[DP, SPFA] Description 物流公司要把一批货物从码头A运到码头B.由于货物量比较大,需要\(n\)天才能运完.货物运输过程中一般要转 停好几个码头.物流公司通常会设计一条固定的运 ...

  2. jquery的ajax用法

    api参见:http://api.jquery.com/jquery.ajax/

  3. 第四讲_图像识别之图像分类Image Classification

    第四讲_图像识别之图像分类Image Classification 目录 图片分类 性能指标:top1,top5 ILSVRC:每种任务数据集不一样 imageNet:根据WorldNet组织的图片集 ...

  4. angular md-toast 颜色

    How to show md-toast with background color https://codepen.io/neilkalman/pen/jWBqve <div ng-contr ...

  5. vue2.0 自定义 饼状图 (Echarts)组件

    1.自定义  图表  组件 Echarts.vue <!-- 自定义 echart 组件 --> <template> <div> <!-- echart表格 ...

  6. python(5)- 简单练习:python三级菜单优化

    python三级菜单优化,菜鸟版链接:http://www.cnblogs.com/xuyaping/p/6648170.html menu = { '北京':{ '海淀':{ '五道口':{ 'so ...

  7. Linux中du和df

    Linux运维过程中,常常发现du和df返回值不一样,偶尔会发现区别非常大. 特定情况下,可能df看到磁盘已满,可是du推断磁盘剩余空间非常大. 文件系统分配当中的一些磁盘块用来记录它自身的一些数据. ...

  8. Python遍历列表

    #循环遍历列表 nums = [ss,gg,e,fff,bb] #while循环遍历,但是不推荐使用,因为还要把列表的元素数出来 i = 0 while i<5: print(nums[i]) ...

  9. 今日BBC

    1.随身英语 Brain training 怎样训练大脑? link 2.地道英语 In good nick 品质好.没有损坏(主要是指古老的东西,比方古董) link 3.今日新闻 -------- ...

  10. asp.net core 初探 二

    今天用@宇内流云大大的jexus 体验一下生产环境的发布,运行. 生产环境: centos 7 jexus 5.8.1 独立版 包含了mono (mono安装真心痛苦……) 开发环境就是昨天的Ubun ...