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

题目意思:给出一个含有 n 个数的排列:p1, p2, ..., pn-1, pn。紧接着是一个 n * n 的矩阵A,当且仅当 Aij = 1 时,pi 与 pj 可以交换数值。现在问如何交换数值,使得最后得到的排列字典序最小。

  比赛的时候不会做,看了Tutorial 1 的解法,觉得别人做得太巧妙了,出题者也出得很好 ^_^

  可以看这个:http://codeforces.com/blog/entry/15488

它是利用了并查集来做的。如果遇到 Aij = 1 的话,就将点 i 和 点 j 连一条边。最终会得到一些互不相交的集合。以第一组 test 来说吧~~~

  

  

  这就表示位置 1、4、7 的数是可以交换的,位置 2、5 要保持原封不动,位置 3、6 的数可以交换。由于每个集合都有一个祖先,即第一层的那个数,依次为 7、2、5、6,然后就把每个集合的数放到以该集合祖先为首的 vector 数组里面,并把每个集合内的数从小到大排序。最后遍历位置 1 ~ n,根据每个位置的数所属的集合(以哪个祖先为首),依次输出。

  只能说,解题思路真是太巧妙兼神奇!竟然可以转化成图!继续干爸爹吧 ^_^

  

 #include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std; const int maxn = + ;
int p[maxn], cnt[maxn];
int group[maxn];
char s[maxn];
vector<int> vi[maxn]; int find(int x)
{
if (x == group[x])
return x;
return group[x] = find(group[x]);
} void merge(int x, int y)
{
int fx = find(x);
int fy = find(y);
if (fx != fy)
group[fx] = fy;
} int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
#endif // ONLINE_JUDGE
int n;
while (scanf("%d", &n) != EOF)
{
vi[n].clear();
for (int i = ; i <= n; i++) {
scanf("%d", &p[i]);
group[i] = i;
}
for (int i = ; i <= n; i++) {
scanf("%s", s+);
for (int j = ; j <= n; j++) {
if (s[j] == '') {
merge(i, j);
}
}
}
for (int i = ; i <= n; i++) {
vi[find(i)].push_back(p[i]); // 千万不要写成 vi[group[i]].push_back(p[i]);
}
for (int i = ; i <= n; i++) {
sort(vi[i].begin(), vi[i].end());
}
memset(cnt, , sizeof(cnt));
for (int i = ; i <= n; i++) {
int g = group[i];
printf("%d%c", vi[g][cnt[g]++], i == n ? '\n' : ' ');
}
}
return ;
}

  注意,代码中的 51 行的部分,如果写成 vi[group[i]].push_back(p[i]) 是错的!以第二个 test 为例,group[1] = 3,find[1] = 5。find[i] 才会找到最终的祖先!!!

codeforces 500B.New Year Permutation 解题报告的更多相关文章

  1. codeforces B. Levko and Permutation 解题报告

    题目链接:http://codeforces.com/problemset/problem/361/B 题目意思:有n个数,这些数的范围是[1,n],并且每个数都是不相同的.你需要构造一个排列,使得这 ...

  2. Codeforces Educational Round 92 赛后解题报告(A-G)

    Codeforces Educational Round 92 赛后解题报告 惨 huayucaiji 惨 A. LCM Problem 赛前:A题嘛,总归简单的咯 赛后:A题这种**题居然想了20m ...

  3. codeforces 476C.Dreamoon and Sums 解题报告

    题目链接:http://codeforces.com/problemset/problem/476/C 题目意思:给出两个数:a 和 b,要求算出 (x/b) / (x%b) == k,其中 k 的取 ...

  4. Codeforces Round #382 (Div. 2) 解题报告

    CF一如既往在深夜举行,我也一如既往在周三上午的C++课上进行了virtual participation.这次div2的题目除了E题都水的一塌糊涂,参赛时的E题最后也没有几个参赛者AC,排名又成为了 ...

  5. codeforces 483C.Diverse Permutation 解题报告

    题目链接:http://codeforces.com/problemset/problem/483/C 题目意思:给出 n 和 k,要求输出一个含有 n 个数的排列 p1, p2, ...,pn,使得 ...

  6. codeforces B. Permutation 解题报告

    题目链接:http://codeforces.com/problemset/problem/359/B 题目意思:给定n和k的值,需要构造一条长度为2n(每个元素取值范围只能是[1,2n])且元素各不 ...

  7. codeforces 507B. Amr and Pins 解题报告

    题目链接:http://codeforces.com/problemset/problem/507/B 题目意思:给出圆的半径,以及圆心坐标和最终圆心要到达的坐标位置.问最少步数是多少.移动见下图.( ...

  8. codeforces B. Xenia and Ringroad 解题报告

    题目链接:http://codeforces.com/problemset/problem/339/B 题目理解不难,这句是解题的关键 In order to complete the i-th ta ...

  9. codeforces 462C Appleman and Toastman 解题报告

    题目链接:http://codeforces.com/problemset/problem/461/A 题目意思:给出一群由 n 个数组成的集合你,依次循环执行两种操作: (1)每次Toastman得 ...

随机推荐

  1. CF469D Two Set (并查集)

    Codeforces Round #268 (Div. 2)D Codeforces Round #268 (Div. 1)B CF468B D. Two Sets time limit per te ...

  2. 希望各位博友能对我的自我介绍提出意见(要面试IBM的应用开发工程师,本科应届生一枚)

    面试官你好,首先我非常高兴能参加今天的面试. 我叫XXX(我名字里面有光宗耀祖),也许父母希望我光宗耀祖吧,所以给我起这样的名字.我的家乡山西太原,本科就读于XX大学,专业是信息与计算科学. 我今天要 ...

  3. Web渗透测试使用Kali Linux(一)渗透测试概要及环境部署

    渗透测试是利用已经发现的漏洞,采用恶意黑客的惯用手段来尝试对漏洞进行攻击. Kali Linux是BackTrack的进化版,是Linux的衍生版本,专门开发用作渗透测试,其中提供了很多的渗透测试工具 ...

  4. 浅谈checkpoint与内存缓存

    事务日志存在检查点checkpoint,把内存中脏数据库写入磁盘,以减少故障恢复的时间,在此之前有必要提下SQL Server内存到底存放了哪些数据? SQL Server内存使用 对SQL Serv ...

  5. 关于EXCEL学习的那些事

    由于在客服中心工作,虽然日常工作基本与数据打交道,但是周围的同事对EXCEL基本不怎么了解,仅会一些基本操作.所以基本日常我会被问到许多EXCEL相关的问题,也针对这个做了一些整理与思考. 之后无意看 ...

  6. nyoj 236心急的C小加 动态规划( java)

    sort函数用法: #include<algorithm> using namespace std; sort(a,a+len;cmp)    //a-->数组名,    len-- ...

  7. 一张图告诉你,只会CSS还不够!

    会了CSS语法.会了CSS选择器,你就真的会了CSS吗,来看这张图!是超实用的CSS代码段的导览!熊孩子们,赶紧学习去吧! 这是一个Web开发最好的时代,每天都有30000条职位信息,面向互联网,我们 ...

  8. eclipse中如何将java项目转为java Web项目

    有时候我们在eclipse中导入web项目时,系统当做一个java项目导入进来了.这时候在启动tomcat的服务器时无法找到该项目. 那么可以通过如下操作来将java项目转换为web项目. 1. 选择 ...

  9. C\C++ 字符串的格式化与类型转化

    字符串格式化 1.sscanf int sscanf(const char *buffer,const char *format,[argument ]...) 取到指定字符为止的字符串.如在下例中, ...

  10. CentOS-6.5安装zabbix 3.0.4

    关闭selinux [root@localhost /]# sed -i "s#SELINUX=enforcing#SELINUX=disabled#g" /etc/selinux ...