经过深思熟虑之后,小贱君打算去M国闯一闯,那是一个古老的东方国度,传说有很多高阶魔法师,他想成为一名伟大的魔法师,将来征服星辰大海。
经过千辛万苦,小贱君终于来到了M国,不幸的是刚进城门小贱君就被M国的守城士兵困在了一种叫做“困兽之斗”的阵法之中。
士兵对小贱君说:“看到漂浮在你身边的宝石了吗?彩虹连接的两颗宝石可以任意交换位置,你需要通过一系列交换后使得宝石组成的字符串的字典序最小。若不能破阵,那还是请回吧!”
小贱君观察了一下周围的宝石,只见每颗宝石上标有一个小写字母,而且有一些宝石上通过彩虹与其他宝石相连。
琢磨了半天,他终于搞懂了这个阵法的意思:
若宝石系列为:dcba
其中有两道彩虹,分别是(0,1),(1,2),代表第一个位置上的宝石可以和第二个位置上的宝石互换,第二个位置上的宝石可以和第三个位置上的宝石互换,最终可以得到字典序最小的宝石系列:bcda。
作为小贱君的死党,你有什么方法帮助他破阵吗?
输入描述:
输入包含多组测试数据。 对于每组测试数据: 字符串s --- 代表宝石序列 n --- 代表有n条彩虹 接下来n行,每行两个数ai,bi --- 表示ai和bi由一条彩虹相连。 保证: 1<=s的长度<=10000 1<=n<=10000 且输入数据均合法。
输出描述:
对于每组数据,输出一个字符串
输入例子:
dcba 2 0 1 1 2 hellonowcoder 4 0 1 1 4 2 5 2 3
输出例子:
bcda ehllonowco方法一:
/******************************************
*@time 2016/08/27 20:58
*@place dhu.13f.5005
*description 并查集+选择排序
***************************************/
#include<cstdio>
#include<cstring>
#include<map>
#include<iostream>
using namespace std;
int Union[10001];
int find_Root(int node)//找到根节点
{
int tmp=node;
while(tmp!=Union[tmp])
{
tmp=Union[tmp];
}
Union[node]=tmp;//此处为优化,缩短查找距离
return tmp;
}
void creat_Tree(int be,int en)//创建并查集
{
be=find_Root(be);
en=find_Root(en);
if(en!=be)
{
if(en>be)
{
Union[be]=en;
}
else
Union[en]=be;
}
}
void init(int num_Of_Nodes)
{
for(int i=0;i<num_Of_Nodes;i++)
{
Union[i]=i;
}
}
int main()
{
char str[10001];
while(scanf(" %s",str)!=EOF)
{
int num_Of_Routes;
scanf("%d",&num_Of_Routes);
int num_Of_Nodes=strlen(str);
init(num_Of_Nodes);
for(int i=0;i<num_Of_Routes;i++)
{
int be;
int en;
scanf("%d %d",&be,&en);
creat_Tree(be,en);
}
for(int i=0;i<num_Of_Nodes-1;i++)//选择排序
{
for(int j=i+1;j<num_Of_Nodes;j++)
{
if(find_Root(i)==find_Root(j)&&str[i]>str[j])//如果点在同一棵树中,那么他们就可以交换
{
char t=str[i];
str[i]=str[j];
str[j]=t;
}
}
}
printf("%s\n",str);
}
return 0;
}
方法二:
/******************************************
*@time 2016/08/27 20:58
*@place dhu.13f.5005
*description 并查集
***************************************/
#include<cstdio>
#include<map>
#include<cstring>
#include<vector>
#include<algorithm>
using namespace std;
int Union[10001];//储存并查集
int find_Root(int node)//找到根节点
{
int tmp=node;
while(tmp!=Union[tmp])
{
tmp=Union[tmp];
}
Union[node]=tmp;//此处为优化,缩短查找距离
return tmp;
}
void creat_Tree(int be,int en)//创建并查集
{
be=find_Root(be);
en=find_Root(en);
if(be!=en)
{
Union[en]=be;
}
}
void inti(int num_Of_Nodes)//初始化
{
for(int i=0;i<num_Of_Nodes;i++)
{
Union[i]=i;
}
}
int main()
{
char str[10001];
while(scanf(" %s",str)!=EOF)
{
int num_Of_Routes;
scanf("%d",&num_Of_Routes);//彩虹数目
int num_Of_Nodes=strlen(str);//字符数
inti(num_Of_Nodes);
for(int i=0;i<num_Of_Routes;i++)
{
int be;
int en;
scanf("%d %d",&be,&en);
creat_Tree(be,en);
}
map<int,vector<int> > trees;//将每棵树的所点的下标储存在一个Vector中
map<int,vector<char> > strs;//将每棵树的所点的内容储存在一个Vector中
for(int i=0;i<num_Of_Nodes;i++)
{
int root=find_Root(i);
trees[root].push_back(i);
strs[root].push_back(str[i]);
}
for(int i=0;i<trees.size();i++)
{
sort(trees[i].begin(),trees[i].end());//排序,使下标从小到大 排列
sort(strs[i].begin(),strs[i].end());//字符排序
}
for(int i=0;i<trees.size();i++)//将排行序的字符插入到字符串中
{
for(int j=0;j<trees[i].size();j++)
{
str[trees[i][j]]=strs[i][j];
}
}
printf("%s\n",str);
}
}