zoukankan      html  css  js  c++  java
  • SPOJ LEXSTR 并查集

    题目描述:

    Taplu and Abhishar loved playing scrabble. One day they thought of inventing a new game using alphabet tiles. Abhishar wrote a string using tiles and gave a set of pairs (i,j) to Taplu.

    Pair “i, j” (0 based indexing) means that Taplu can swap the i’th and j’th tile in the string any number of times.  

    He then asks Taplu to give the lexicographically smallest string that can be produced by doing any number of swaps on the original string.

    Input

    First line contains T(1<=T<=10), the number of testcases.

    First line of each test case contains the initial string S. Length of Sttring is len(1<=len<=100000).

    Next line contains the number of pairs M (1<=M<=100000).

    Next M lines contains pairs i j that means ith character can be swapped with jth character.

    Note - i and j can be same and same i,j pair can occur twice.

     

    Output

    For each testcase output the lexicographically smallest string that can be made from the initial string.

    Example

    Input:

    1
    lmaf

    3
    0 1
    1 2
    2 3 Output: aflm

    题目的意思是给你一个字符串,然后给你n对位置,每一对位置上的两个字符可以进行无数次交换,问你进行足够多的交换后,你能得到的最小字典序的字符串是什么?

    如果想到并查集的话,就是把这n对位置进行集合上的合并,然后就变成了几个集合,这几个集合里面存的是一堆位置,在同一集合的位置能互换。
    现在我们只要每个集合中位置所对应的字符按照字典序排个序,每个集合都满足字典序最小,这样整体拼起来就也应该是最小的字典序。

    代码如下:
     1 #include <bits/stdc++.h>
     2 
     3 using namespace std;
     4 const int maxn =100800;
     5 vector<char> e[maxn];
     6 char s[maxn];
     7 int h[maxn];
     8 int father[maxn],l;
     9 int t,n;
    10 int Find(int x)
    11 {
    12     if (father[x]==x)
    13         return x;
    14     return father[x]=Find(father[x]);
    15 }
    16 void Union (int x,int y)
    17 {
    18     int fx=Find(x),fy=Find(y);
    19     if (fx!=fy);
    20     father[fx]=fy;
    21 }
    22 void init()
    23 {
    24     for (int i=0;i<maxn;++i)
    25         e[i].clear();
    26     memset(h,0,sizeof h);
    27     for (int i=0;i<maxn;++i)
    28         father[i]=i;
    29 }
    30 int main()
    31 {
    32     //freopen("de.txt","r",stdin);
    33     scanf("%d",&t);
    34     while (t--){
    35         init();
    36         scanf("%s",s+1);
    37         l=strlen(s+1);
    38         scanf("%d",&n);
    39         for (int i=0;i<n;++i){
    40             int a,b;
    41             scanf("%d%d",&a,&b);
    42             Union(++a,++b);
    43         }
    44         for (int i=1;i<=l;++i)
    45             e[Find(i)].push_back(s[i]);//将对应位置的字符加入vector,以便排序
    46         for (int i=1;i<=l;++i)
    47             sort(e[i].begin(),e[i].end());//将每个集合中的字母排序
    48         for (int i=1;i<=l;++i){
    49             int tmp=Find(i);//找到当前位置所在集合的代表元素
    50             printf("%c",e[tmp][h[tmp]++]);//输出当前集合的h[tmp]++个元素,h[]数组用于统计集合内已经输出了几个元素
    51         }
    52         printf("
    ");
    53     }
    54     return 0;
    55 }


  • 相关阅读:
    在vue项目中使用stylus来实现移动端的1px
    Promise对象和回调函数,解决异步数据传递问题
    axios在实际项目中的使用介绍
    关于React.PropTypes的废除,以及新版本下的react的验证方式
    javascript之日期对象
    js Date 日期格式化(转)
    jquery无缝隙连续滚动代码
    8款惊艳的HTML5粒子动画特效
    web前端设计师们常用的jQuery特效插件汇总
    js/jQuery实现类似百度搜索功能
  • 原文地址:https://www.cnblogs.com/agenthtb/p/6500525.html
Copyright © 2011-2022 走看看