經過深思熟慮之後,小賤君打算去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);
}
}